非常感谢任何回复。
PHP有一个名为tmpfile的函数。它会创建一个临时文件并返回一个资源。这个资源可以像其他资源一样使用。
例如,手册中的示例:
<?php
$temp = tmpfile();
fwrite($temp, "writing to tempfile");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file
?>
文件会在关闭(使用fclose())时自动删除,或者在脚本结束时删除。您可以在资源上使用任何文件函数。 您可以在这里找到它们。希望这可以帮助您?
另一种解决方法是以常规方式创建文件,并使用cron作业定期检查会话是否过期。过期日期和其他会话数据可以存储在数据库中。 使用脚本查询该数据并确定会话是否已过期。如果是,则从磁盘物理上将其删除。确保每小时运行一次脚本(取决于超时时间)。
所以,我们有一个或多个文件可供下载。为每个下载请求创建临时文件不是一个好主意。相反,为每个文件创建symlink()
是一个更好的选择。这将节省大量磁盘空间并降低服务器负载。
将符号链接命名为用户会话名称是一个不错的主意。更好的主意是生成一个随机符号链接名称并与会话相关联,以便脚本可以处理单个会话中的多个下载。您可以使用session_set_save_handler()
(链接)并注册一个自定义read
函数来检查过期会话并在会话过期时删除符号链接。
好的,目前我们有以下需求:
让我们看看。这不是可运行的代码,但它应该按照这些思路工作:
<?php // download.php
session_start(); // start or resume a session
// always sanitize user input
$fileId = filter_input(INPUT_GET, 'fileId', FILTER_SANITIZE_NUMBER_INT);
$token = filter_input(INPUT_GET, 'token', FILTER_UNSAFE_RAW);
$referer = filter_input(INPUT_SERVER, 'HTTP_REFERER', FILTER_SANITIZE_URL);
$script = filter_input(INPUT_SERVER, 'SCRIPT_NAME', FILTER_SANITIZE_URL);
// mush session_id and fileId into an access token
$secret = 'i can haz salt?';
$expectedToken = md5($secret . session_id() . $fileId);
// check if request came from download.php and has the valid access token
if(($expectedToken === $token) && ($referer === $script)) {
$file = realpath('path/to/files/' . $fileId . '.zip');
if(is_readable($file)) {
session_destroy(); // optional
header(/* stuff */);
fpassthru($file);
exit;
}
}
// if no file was sent, send the page with the download link.
?>
<html ...
<?php printf('a href="/download.php?fileId=%s&token=%s',
$fileId, $expectedToken); ?>
...
</html>
就是这样,不需要数据库。这应该满足1-3的要求。你不能用PHP控制速度,但如果在发送文件后不销毁会话,你可以将计数器写入会话中,并限制用户在一次会话期间发送的文件数量。
我完全同意,这种猴子表格黑客技巧可以更优雅地解决,但作为概念证明,它应该足够了。
您能详细解释一下您的问题吗?因为我不明白为什么不能使用$_SESSION
。顺便提一下,$_SESSION
中的数据是存储在服务器端的文件中的(请参见http://php.net/session.save-path)。至少默认情况下是这样的。;-)
dl.php?k=hd8DcjCjdCkk123
,然后将此字符串放入数据库中,存储他的IP地址、可能的会话和您生成链接的时间。然后另一个用户请求该文件,确保所有内容(哈希值、IP等)匹配且链接未过期(例如,自生成以来不到N小时),如果一切正常,则使用PHP管道传输文件。设置一个cron作业来查看数据库并删除过期条目。您认为呢?