2016-08-22 71 views
1

我正在开发视频点播网站。下载选项与内容标题和读取文件一起提供。我遇到了一个问题,我只能在下一个文件完成后才能查看或下载其他内容。 我目前的读取文件代码Php执行暂停直到文件被下载

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(); 

可能是什么问题?

+0

我有流媒体内容没有任何经验,但它可能是更好地使用JS去做这个。这是因为带AJAX的JS可以改变一些事情,这是PHP不能做的事 – SuperDJ

+2

您正在体验所谓的会话锁定。 – MonkeyZeus

+1

@MonkeyZeus是的,现在我明白了,谢谢 – coderSree

回答

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(); 
+2

谢谢,这正是我所需要的。学到了新的东西,欢呼:) – coderSree

1

其他请求被阻塞,因为会话文件由这一个锁定。
该解决方案是使用session_write_close功能,

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

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

这是因为会话锁定的。当您拨打session_start()时,PHP会锁定会话文件,以便任何其他进程在锁定释放之前无法使用。发生这种情况是为了防止并发写入。

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

通过传递附加参数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, 
]); 

注中提到:由于手册说,在PHP7加入的选项参数。 (感谢MonkeyZeus指出了这一点)。如果您使用的是旧版本,根据jeroen的回答,您可以使用session_write_close进行尝试。

+3

请注意这一事实,这将只适用于PHP> = 7.x,因为可能OP有一个未升级的主机提供商。 – MonkeyZeus

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);