【问题标题】:PHP Headers confusionPHP 标头混淆
【发布时间】:2011-11-21 12:09:04
【问题描述】:

我整天都在用头撞这个。是时候寻求帮助了。

所以,我有一个 PHP 脚本,它是一个下载页面。用户可以根据自己订购的内容下载文件。

它是这样的(显然不是真正的代码,好吧有些是 - 希望你能明白要点)

PAGE START
if(post[getorder]){

check order exists, get order filename etc from mysql;
update download attempts in db;

$ctype="application/force-download";
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers 
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
$handle = fopen($filename, "r");
while ( $contents = fread( $handle, 1024 ) )
{
print (  $contents );
flush();
}
fclose($handle);    
$successmessage = "Your download has begun";                  
}

if($successmessage){
 echo $successmessage;
}

get users order details from db;
display div
 display form with post to post order number to script; 
 end form
end div
END PAGE

希望这是有道理的。如果这样更有用的话,我可以把所有代码都放上去,但这是一个很长的旧脚本,我认为这可能更方便。

因此,如果用户只是查看页面,脚本会获取用户可能拥有的任何订单的订单信息。在订单被标记为已完成且不再可用之前,用户只能尝试下载 X 次。

它为每个可用订单显示一个 div,每个 div 内部都有一个小表单。如果他们单击表单,它会将订单号发布回相同的脚本,此时我希望它会简单地提供文件,然后继续显示页面的其余部分。唉,不,显然是强制下载抓取控件上的标题,并且在 fclose 之后没有任何反应。

所以我想搞砸了,并在“if(post...)”中添加了一个变量,沿着 $sendfile = 1 的行,并在页面底部...

if($sendfile == 1){ 做标题的东西}

...希望页面在发送文件之前能够正确加载并且每个人都开心。再说一次,唉。它首先提供文件,并且不重新加载页面。

再次,希望我的措辞有意义。

我读过一个 php 脚本会首先“做”标题,所以你把它们放在哪里都没关系。我不知道这是不是真的,但根据我所看到的,它是。

我还尝试在 fclose 之后使用标头重定向到同一页面,并使用简单的 GET 使脚本显示成功消息。但是,如果我这样做,重新加载工作,但不显示下载提示。即使我在重定向到自我之前放了一个 sleep(10) 。它只是等待然后重新加载,但没有文件下载。

页面重新加载非常重要,因为当页面的其余部分重新获取订单数据并显示时,下载尝试次数应该增加1。

有什么方法可以实现我想要做的事情吗?我正在剪切的代码变得越来越hacky,因此非常感谢任何帮助或建议。

【问题讨论】:

  • 我真的不明白你想要什么,或者手头的问题是什么,但你的代码看起来很可疑。您尝试在下载数据中生成下载和伴随下载的成功消息。如果您想获得成功消息和下载,则需要通过单独的请求生成它们,例如首先生成一个带有“下载开始”消息的页面,页面自动重定向到可以保存的下载,或者通过 iframe 或其他方式提供下载。
  • 嗨 Achimedix,是的,我开始明白你的意思了。我已经有各种方式“将页面本身附加到下载文件的开头或结尾” - 您可以发送页面或发送文件,但不能同时发送?这是我的理解的问题,我只是不明白为什么你不能先加载页面,然后执行脚本的“发送文件”部分......

标签: php header fclose


【解决方案1】:

在下载登录页面上,尝试添加 <meta http-equiv="refresh" content="1; url=/download/file/url"> 而不是使用标题。这将使浏览器加载页面,然后在 1 秒后重定向到文件下载。

此外,如果您提供的不是小文件,我建议您查看X-Sendfile

【讨论】:

  • 您好 Znarkus,感谢您的输入 - 文件大小从 40mb 到 300mb 不等 - 可以保证 X-Sendfile 吗?我查看了 XSendfile 页面,看起来这也是在标题中完成的,所以我不会再次遇到同样的问题吗?
  • 嗨 Znarkus,我想我看到了你(和 Archimedix)的意思——我猜根据其他网站的做法,如果我将用户重定向到“你的文件正在下载”页面怎么样,并从该页面提供文件?这应该可以解决我遇到的问题,不是吗?
  • 这就是我的建议 :) 我的“下载登陆页面”就是您所说的“您的文件正在下载”页面。我认为 X-Sendfile 在服务器上更容易,所以它可能值得一试。不是为了解决这个问题,而是为了“面向未来”。只需确保从源代码编译最新的。
  • 嗨 Znarkus - 谢谢,当我们获得新服务器时,我会考虑将 XSendfile 放入其中。感谢您提供有关刷新的指针,我最终确实这样做了,但如果我没有那一点信息,我会非常卡住 - 所以感谢您的帮助。
猜你喜欢
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-22
  • 2011-09-10
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
相关资源
最近更新 更多