2011-11-21 98 views
0

我一整天都在对这个问题猛撞我的头。有时间寻求一些帮助。PHP标题混淆

所以,我有一个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后。

所以我想开溜了,和沿$的sendfile = 1,就在页面底部的线条增加了一个变量到:“如果(后...)” ...

如果($ sendfile == 1){do headers stuff}

...希望在发送文件之前页面能够正确加载并且大家都开心。再次,唉,没有。它首先提供文件,并且不会重新加载页面。

再一次,希望我的措词有道理。

我读过,PHP脚本会'首先'做标题,所以无所谓你把它们放在哪里。我不知道这是否属实,但基于我所看到的情况是这样。

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

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

有什么办法来实现什么我正在努力?我正在削减的代码越来越黑,所以任何帮助或建议将非常感激。

+1

我真的不明白你想要什么,或者手头的问题是什么,但是你的代码通常看起来很可疑。您尝试在下载数据中生成下载和成功消息以及下载内容。如果您想获得成功消息和下载,则需要通过单独的请求(例如,通过首先生成具有“下载开始”消息的页面,页面自动重定向到可以保存的下载,或者通过iframe或通过其他方式提供下载。 – Archimedix

+0

嗨Achimedix,是的,我开始明白你的意思了。我已经有了“将页面本身附加到下载文件的开始或结尾”的方式 - 是否可以发送页面或发送文件,但不能同时发送?这是我的理解,我只是不明白为什么你不能先加载页面,然后做“发送文件”部分的脚本... –

回答

1

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

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

+0

嗨Znarkus感谢您的输入 - 文件将从各地不同40mb到300mb - 会保证X-Sendfile吗?我查看了XSendfile页面,看起来这也是在头文件中完成的,所以我不会再次遇到同样的问题吗? –

+0

嗨Znarkus,我想我看到你(和Archimedix)正在获得什么 - 我想基于其他网站做什么,如果我将用户重定向到“您的文件正在下载”页面,并从该网站提供文件页?这应该工作,并绕过我所拥有的probs应该不是吗? –

+0

这就是我提出的:)我的“下载着陆页”就是你所描述的“你的文件正在下载”页面。我认为X-Sendfile在服务器上更容易,所以它可能值得尝试。不是为了解决这个问题,而是为了“未来的证明”。只要确保从源代码编译最新。 – Znarkus