2009-11-18 38 views
2

在我們的應用程序,驗證通過組控制器插件是驗證用戶的處理等即成大文件

我想成爲一個大的(視頻)文件只認證用戶 - 最顯而易見的方法要做到這一點是通過在控制器中的readfile(),但我發現它符合PHP內存限制 - 大概是控制器的輸出緩衝在某處。

如何才能關閉緩衝只爲這一個控制器?

編輯:感謝所有關於刷新任何現有的輸出緩衝有用的提示 - 我想我是專門尋找在框架內做到這一點的方式,但?

回答

-1

我不認爲你真的可以。據我所知php在發送給請求者之前緩衝所有輸出。

,你可以增加使用ini_set()

+0

不正確,PHP具有控制輸出緩衝區的功能。 – 2009-11-18 10:20:59

+0

是的,你可以控制我,但你不能緩衝它... – NDM 2009-11-18 10:34:17

+0

誠然,你不能完全關閉它,但你絕對可以阻止它達到內存限制。 – 2009-11-18 10:46:25

0

使用外部腳本輸出的文件考慮到內存限制,並且它傳輸到使用PHP的passthru功能的瀏覽器。

如果一個基於Linux的系統上,你可以嘗試像passthru("cat video_file.flv");

然而,更好的做法是完全避免這個流(從PHP內),併發出客戶端301 HTTP重定向的URL實際的靜態資源,以便網絡服務器可以直接處理流式傳輸。

+1

這意味着資源可以由未經身份驗證的人公開訪問,只要他們知道URL – 2009-11-18 11:10:20

+1

在Zend_Controller動作中使用'passthru'仍然會遇到與原始問題中描述的問題相同的問題 - 控制器(特別是Response對象)會在輸出之前緩存結果。 – jcsanyi 2015-09-20 20:21:09

4

有趣的問題......你可以嘗試:

// ... 
public function largeFileAction() 
{ 
    // this clears all active output buffers 
    while (ob_get_level()) { 
     ob_end_clean(); 
    } 
    readfile('path/to/large/file'); 
    exit(); // to prevent further request handling 
} 
// ... 
-1
$handle = fopen('/path/to/file', 'r'); 
$chunk_size = 8192; 

while ($chunk = fread($handle, $chunk_size)) { 
    echo $chunk; 
    ob_flush(); 
} 

這可能需要一些調整,如添加正確的標題,如果需要讀取二進制模式,但其基本思想是健全的。我已經成功地使用這種方法來發送50 + MB文件,並具有16 MB的PHP內存限制。

+0

謝謝,這是專門在Zend Framework環境中嗎? – 2009-11-18 10:35:49

+0

對不起,這不是Zend特有的,它只是我知道阻止大文件填滿內存限制的唯一方法(當然,除了使用不綁定PHP進程的方法) – 2009-11-18 11:17:15

+0

我認爲這是隻要框架沒有嘗試控制輸出緩衝區,就不是Zend特有的。我在32MB環境下以這種方式輸出了700MB的文件(這是因爲執行時間的限制)。 – 2009-11-18 12:05:26

2

好的,我可能在這裏完全錯誤,但我認爲有必要在某處讀取OB,因此必須爲ZendLayout和佔位符助手啓用OB,因此您必須爲downloadAction禁用它們(您可能不需要他們無論如何都要爲文件提供服務)。

會這樣的事情實現你想要做的事情嗎?

class DownloadController 
{ 
    public function downloadAction() 
    { 
     $this->_helper->layout()->disableLayout(); 
     $this->_helper->viewRenderer->setNoRender(true); 
     // authenticate user if not done elsewhere already 
     header(/* ... the usual stuff ... */); 
     filepassthru(/* some path outside webroot */); 
     exit; 
    } 
} 
2

泰森寫道,你最好的選擇(如果你有對服務器的完全控制)是驗證用戶憑證和重定向他(302臨時重定向)的地方,他可以下載該文件的URL。

爲了防止重複使用這些URL,我們使用Lighttpd及其mod_secdownload,它允許您生成一個在指定的時間內有效的散列。

nginx有X-Accel-Redirect和Apache有mod_xsendfile

如果您決定實施一個單獨的輕量級的Web服務器也有其他好處(主要是較低的內存消耗,同時提供靜態文件和更快的響應時間)。

如果您決定走這條路線,您將不得不向服務器添加另一個IP地址,並且僅將Apache綁定到一個IP地址,而將另一個服務器(對nginx輕微)綁定到另一個服務器,因爲它們是Web服務器兩者都在端口80上偵聽。並且更改其中一個服務器的端口不是一個好主意,因爲很多人無法訪問更高端口。

如果添加另一個IP地址不是一個選項,您可以在端口80上安裝nginx並將其用作反向代理以將動態請求傳遞給Apache,以便在另一個端口上偵聽並提供所有靜態文件。