2008-11-11 114 views
2

我的大多數PHP應用程序在開始時都有一個ob_start,貫穿所有代碼,然後在完成所有事情之後輸出內容,有時會進行一些修改。如何停止PHP輸出緩衝區超過內存限制?

ob_start() 
//Business Logic, etc 
header->output(); 
echo apply_post_filter(ob_get_clean()); 
footer->output(); 

這確保了PHP錯誤獲取網站的內容部分中顯示,而且錯誤不headersession_*電話干擾。

我唯一的問題是,一些大頁面PHP內存不足。我如何阻止這種情況發生?

一些想法:

  1. 寫的所有內容緩存到一個臨時文件和輸出的。
  2. 當緩衝區達到一定的大小時,輸出它。儘管這可能會影響後期過濾器。
  3. 提高內存限制(thanx @troelskn)。

這些方法的缺點是什麼?尤其是提高內存限制?

回答

5

你不能提高內存限制嗎?聽起來像是我最好的解決方案。

編輯:很明顯,提高內存限制,只是因爲一個腳本頂起應該引起一些紅旗,但這聽起來像這是一個合法的情況 - 例如。該腳本實際上產生相當大的輸出塊。因此,您必須將輸出存儲在某處,而且出於性能和便利的原因,內存似乎是最好的選擇。

我還應該注意,內存限制設置就是這個 - 一個限制。不消耗太多內存的腳本不會因爲你提高限制而消耗更多。其存在的主要原因是爲了防止行爲不當或錯誤的腳本取消整個服務器。如果你有很多業餘愛好者在共享主機上進行黑客攻擊(這個PHP已經被大量使用),這是非常重要的。所以如果這是你自己的服務器,或者至少你通常知道你在做什麼,那麼低內存限制並沒有任何好處。

+0

我認爲這也是最好的方法。 – 2008-11-11 17:51:43

+0

我試過了,但是有些東西在踢我提高內存限制。提高MEM限制的任何缺點? – Jrgns 2008-11-11 18:16:42

2

你應該在任何事情之前提高內存限制,特別是如果你唯一的解決方案是通過臨時文件。

出現的各種缺點的使用臨時文件(主要是,它的速度較慢),如果你真的需要有一種方式outputing之前將其緩衝儲存,去看看memcachedAPC cache。這可以讓你和文件大致相同,除非你有RAM的快速訪問。

不過我必須說這是一個糟糕的主意。如果緩衝區目前無法正常工作,那麼爲了使您的網站能夠更好地工作,您可能會採取不同的構建方式。

2

如果PHP錯誤是緩衝輸出的唯一原因,請考慮使用set_error_handler。使用此功能,您可以在腳本中爲錯誤定義自定義回調。用它來保存消息並稍後打印。

http://www.php.net/set_error_handler

+0

這不僅僅是因爲錯誤。注意改變輸出的apply_post_filter函數。 – Jrgns 2008-11-11 18:35:16

1

爲你出的內存中運行,由於輸出效果,必須有一個巨大的數據外出或非常低的內存限制量。大約4年前,8MB的內存限制已經足夠普遍了,而且是合理的。但是隨着切換到使用對象和更好的編碼風格,我遇到的腳本的內存使用量增加了。

槽糕......它在哪裏,你的腳本運行內存不足?如果它總是在你的輸出過濾功能,也許他們只需要優化? memory_get_usage()將返回腳本在該點使用的內存量。

你當前的內存限制是多少?你是否在共享環境中運行? 目前我已經有64和128之間的內存限制,取決於服務器。

如果它只是要增加,那麼你可以做到這一點每個腳本的限制腳本的特定子集:

ini_set('memory_limit','64M'); 

如果你想爲腳本沒有限制,你可以將其設置爲-1

1

我的建議是嘗試分階段加載文件,或將其拆分成更小的文件以供包含。你如何做到這一點很大程度上取決於文件是什麼,但它可以讓你加載它,如... 2MB塊,如果它不產生任何錯誤,然後你使用ob_flush()發送它在加載下一個塊之前。

例如,你提到它是一個PHP模板;我不確定那究竟是什麼,如果你正在討論一個混合的PHP/HTML文件,當它被執行時會產生輸出,那麼你可以嘗試在模板中添加某種形式的塊標記來分離模板的不同部分。這樣您只需要讀取當前塊的末尾,然後輸出並繼續。如果你有循環或類似的東西,這會變得更加困難,但總是有辦法解決它。例如,通過將PHP添加到您的模板中,該模板可以在主腳本中觸發一個可以分階段處理循環輸出的方法/函數。

您可能也想看看一個機制,預驗證模板加載之前,所以你不必擔心錯誤蔓延到頁面的。

在改變內存限制將「解決」,在短期內它不是一個長期的解決方案的問題,因爲那樣的內存使用的肯定是應儘量避免使用。一般來說,如果可以避免的話,您不希望將任何大的內容加載到內存中,或者儘早將其吐出,因爲這意味着數據至少會在前往用戶的路上,從而將時間縮短到第一次字節的頁面。