2012-07-02 54 views
1

使用MVC框架和控制器在析構函數中呈現頁面。我正在通過php下載文件,因此在操作結束時腳本應該結束。如何在不調用析構函數的情況下退出PHP腳本?

如何在不調用析構函數的情況下結束腳本?

有沒有更好的解決方案?

exit和die調用析構函數。

+0

什麼MVC框架? –

+0

這是一個自定義框架。 –

+1

我覺得很奇怪,頁面將在析構函數方法中呈現。爲什麼不在框架調用的渲染方法中?我錯過了什麼嗎? –

回答

2

正如David所說:您需要在析構函數內調用exit()來停止它。

如果您只是想停止由這些析構函數引起的可視化輸出,而不是其他可能會產生的副作用(文件關閉,數據庫連接關閉),那麼最好僅僅殺死更多輸出,而不要使用析構函數單獨。在我看來,這是一條重要的原因,因爲破壞者往往會在那裏存在:清理。

你可以做到這一點通過操縱緩衝輸出:

<?php 
class Tester{ 
    public function devNull($string){ 
     return ""; 
    } 

    public function runAndBreak(){ 
     print "run" . PHP_EOL; 

     // if any output buffer is working, flush it and close it 
     if(ob_get_level()) ob_end_flush(); 

     // redirect new buffer to our devNull 
     ob_start(array($this,'devNull')); 
     exit(); 
     print "still running"; 

    } 

    function __destruct(){ 
     print "destructor" . PHP_EOL; 
    } 

} 

$t = new Tester(); 
$t->runAndBreak(); 

這將只打印run並沒有什麼在析構函數。這是通過給你自己的回調例程ob_start來處理,然後返回輸出。在我們這裏,我們通過返回一個空字符串來簡單地放棄它。

3

請參閱this answer。 嘗試在下載文件的類中創建一個析構函數,該文件檢查文件是否確實發送給瀏覽器,如果是,請在該析構函數中調用exit()。

+0

您是否將析構函數調用的順序考慮在內?如果你創建$ obj1和$ obj2,析構函數會被稱爲dest2和dest1嗎?或者是當對象超出範圍時指示的順序? –

0

這無疑會阻止你的腳本,但要小心,如果你運行這樣的服務器,其中一個進程可以有以下幾個PHP請求那些將停止,以及:

$pid = getmypid(); 
exec("kill $pid"); 
exec("TSKILL $pid"); 
相關問題