2016-08-22 70 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);