【问题标题】:Delay unlink after HeaderHeader 后延迟取消链接
【发布时间】:2018-01-19 11:23:16
【问题描述】:

我正在尝试为登录用户创建一个安全的文档检索系统。

首先,我检查用户是否已登录。如果是,我将文件从服务器上的受保护目录复制到用户当前目录中的 Web 可访问空间。

然后我将它们重定向到文件现在所在的 URL。让代码休眠 10 秒,让慢速连接有时间下载文件,然后将其删除,这样其他人就无法再使用该链接。

我的问题是,在标题之后,睡眠功能不起作用。我尝试删除 if 语句,这使脚本休眠 10 秒,然后在重定向用户之前取消链接文件,因此链接已经断开。

我正在努力寻找一种方法让脚本休眠 10 秒,并在重定向发生后仍然执行代码。

    <?php
if(!isset($_SESSION['id'])){
header("location:../../../");
}
else {
    echo copy('C:\directorypath\test.xls','test.xls');
    if(header("location:../docs/test.xls")){
    sleep("10");
    unlink("test.xls");
    }
}
    ?>

【问题讨论】:

  • 感谢 Hamza,我在代码中使用睡眠功能没有问题,问题在于何时发生这种情况。我希望它在 if 语句返回为 true 之后休眠,但它在任何操作发生之前就开始了。
  • PHP 本质上是单线程的,这是不可能的。当header 行被执行时,脚本的其余部分被终止。没有办法既返回文件,同时也删除它。这不是 PHP 的工作方式。
  • 您应该通过 php 提供文件,而不是将其复制到公共目录。
  • 如果文件那么小,那么恕我直言,首先通过 PHP 脚本处理下载(而不是在 HDD 上复制文件)会更有意义。

标签: php unlink


【解决方案1】:

您尝试做的实际上是用 PHP 做不到的,因为 PHP 是单线程的,并且对于每个请求从头到尾执行。这意味着在脚本中的所有代码完成之前,header 重定向不会完成。这意味着脚本将首先等待,然后删除文件,然后尝试重定向到非退出文件。

相反,我打算采用另一种方法;使用和存储只能使用一次的唯一哈希。

检查用户是否已登录。如果他或她已登录,则生成唯一的哈希并将其插入数据库中,例如INSERT INTO hashes (hash, used) VALUES ($myUniqueHash, 0)。然后将用户重定向到请求查询中带有哈希的 PHP 文件,例如

header("Location: serve_file.php?hash=$myUniqueHash");

此文件将根据包含哈希的表检查$_GET['hash'] 的值,并检查used 的值是否为0。如果是这种情况,它会将used 列更新为1serve the file as a proxy。如果未找到哈希,或者used 列的值不是0,则会返回错误。

这样我们可以只为登录用户提供一次(秘密)文件。

【讨论】:

  • 谢谢你,一个非常详细的答案,我现在就去。
  • "这意味着直到你脚本中的所有代码都完成后才完成标头重定向"错误!你应该看看flush()this question
  • @rlanvin 是的。您可以刷新内容,但您如何知道文件是否已完成下载?最初的想法是使用 10 秒的超时来“确保慢速连接也能下载文件”,在我看来,这是非常容易出错的方法。用于文件代理的一次性令牌是解决此类问题的更常见方法。
  • 当然它容易出错并且完全有缺陷。但是以“用 PHP 做不到”来开始你的回答是不正确的。这是可能的,但由于您所说的原因,这是不可取的。
  • 只是在这里大声思考...基于用户名的哈希创建一个临时目录会不会产生相同的效果?我的意思是我真的希望这个下载窗口有时间限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
相关资源
最近更新 更多