Php执行暂停直到下载文件

时间:2016-08-22 12:25:52

标签: php

我正在开发视频点播网站。下载选项随内容标头和readfile一起提供。我遇到问题,只有在完成上一个文件的下载后才可以查看或下载其他内容。 我当前的readfile代码

session_start();
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename='.$_SESSION['file']);
//set_time_limit(0);
readfile($_SESSION['file']); 
exit();

可能是什么问题?

4 个答案:

答案 0 :(得分:3)

问题在于会话:只要此请求正在运行,会话就会被锁定,因此您无法执行任何使用相同会话的操作。

解决方案是将文件名的值分配给另一个变量,并在将内容输出到浏览器之前关闭会话。

例如:

session_start();
$filename = $_SESSION['file'];
// close the session
session_write_close();

// output the data
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename='.$filename);
//set_time_limit(0);
readfile($filename); 
exit();

答案 1 :(得分:1)

其他请求被阻止,因为会话文件被此锁定 解决方案是在使用session_write_close函数

调用readfile之前关闭会话 像这样:

<?php
$file = $_SESSION['file'];
session_write_close();
readfile($file); 
?>

答案 2 :(得分:1)

由于会话锁定而导致这种情况。当您调用session_start()时,PHP会锁定会话文件,因此任何其他进程都无法使用,直到锁定被释放。这是为了防止并发写入。

因此,当其他请求到达服务器时,PHP会等待session_start()行,直到它能够使用session,即第一个请求结束时。

您可以通过传递其他参数read_and_close只读中打开会话。如session_start() manual - example #4

中所述
<?php
// If we know we don't need to change anything in the
// session, we can just read and close rightaway to avoid
// locking the session file and blocking other pages
session_start([
    'cookie_lifetime' => 86400,
    'read_and_close'  => true,
]);

注意:正如手册所说,options参数是在PHP7中添加的。 (感谢MonkeyZeus指出这一点)。如果您使用的是旧版本,可以根据jeroen的回答尝试使用session_write_close

答案 3 :(得分:0)

由于其他答案都是纯PHP解决方案,我想提供mod_xsendfile的惊人功能和PHP后备:

session_start();

// Set some headers
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename='.$_SESSION['file']);

if(in_array('mod_xsendfile', apache_get_modules()))
{
    header("X-Sendfile: ".$_SESSION['file']);
}
else
{
    $file = $_SESSION['file'];
    // close the session
    session_write_close();


    //set_time_limit(0);
    readfile($file); 
}

exit(0);