2015-06-19 21 views
2

我的腳本在PHP中被終止後,嘗試執行一些最終代碼。所以我們可以說我有這個PHP腳本:在CLI中腳本中止後執行代碼

while(true) { 
    echo 'loop'; 
    sleep(1); 
} 

如果我$ php script.php執行該腳本運行它的,直到給定的執行時間。

現在我喜歡在腳本被中止後執行一些最終代碼。所以,如果我

  • Ctrl+C
  • 執行時間超過

是否有甚至可能做這些情況下,一些清理?我試過pcntl_signal但沒有運氣。還有register_shutdown_function,但只有在腳本成功結束時纔會調用該函數。

UPDATE

我發現(感謝RCH的鏈接),我不知能 「抓住」 的事件:

pcntl_signal(SIGTERM, $restartMyself); // kill 
pcntl_signal(SIGHUP, $restartMyself); // kill -s HUP or kill -1 
pcntl_signal(SIGINT, $restartMyself); // Ctrl-C 

但是,如果我延長我的代碼以

$cleanUp = function() { 
    echo 'clean up'; 
    exit; 
}; 

pcntl_signal(SIGINT, $cleanUp); 

如果我點擊Ctrl+C,腳本會繼續執行,但不會遵守$cleanUp關閉中的代碼。

回答

3

功能pcntl_signal()是腳本進入時情況的答案使用Ctrl-C(和其他信號)中斷。你必須注意文檔。它說:

您必須使用declare()語句來指定您的程序中允許回調被允許發生的位置,以使信號處理程序正常工作。

declare()聲明,除其他事項外,通過調用函數pcntl_signal_dispatch()這反過來又要求你安裝了信號處理程序將安裝處理自上次調用接收到的信號的調度回調函數。

或者,如果您認爲適合您的代碼流(並且根本不使用declare(ticks=1)),則可以自己調用函數pcntl_signal_dispatch()

這是一個使用declare(ticks=1)一個示例程序:

declare(ticks=1); 

// Install the signal handlers 
pcntl_signal(SIGHUP, 'handleSigHup'); 
pcntl_signal(SIGINT, 'handleSigInt'); 
pcntl_signal(SIGTERM, 'handleSigTerm'); 


while(true) { 
    echo 'loop'; 
    sleep(1); 
} 

// Reset the signal handlers 
pcntl_signal(SIGHUP, SIG_DFL); 
pcntl_signal(SIGINT, SIG_DFL); 
pcntl_signal(SIGTERM, SIG_DFL); 



/** 
* SIGHUP: the controlling pseudo or virtual terminal has been closed 
*/ 
function handleSigHup() 
{ 
    echo("Caught SIGHUP, terminating.\n"); 
    exit(1); 
} 

/** 
* SIGINT: the user wishes to interrupt the process; this is typically initiated by pressing Control-C 
* 
* It should be noted that SIGINT is nearly identical to SIGTERM. 
*/ 
function handleSigInt() 
{ 
    echo("Caught SIGINT, terminating.\n"); 
    exit(1); 
} 

/** 
* SIGTERM: request process termination 
* 
* The SIGTERM signal is a generic signal used to cause program termination. 
* It is the normal way to politely ask a program to terminate. 
* The shell command kill generates SIGTERM by default. 
*/ 
function handleSigTerm() 
{ 
    echo("Caught SIGTERM, terminating.\n"); 
    exit(1); 
} 
+0

Thx!奇蹟般有效。你能告訴我爲什麼我必須重置信號處理程序嗎?我認爲這是我在pcntl_signal和'ticks = 1'的方法中錯過的... – TiMESPLiNTER

+1

我不知道重置信號處理程序是否能夠完成這項工作。我習慣於把它們放在那裏,關閉打開的文件,破壞構造的對象,釋放分配的資源a.s.o,這是一種很好的編碼習慣。如果你不想立即退出(),而是想做額外的處理,建議在信號處理程序中設置一個標誌,並在主程序循環中檢查它並相應地進行處理(或者使用'pcntl_signal_dispatch()'來代替'declare(ticks = 1)'。你可以閱讀更多關於[終止信號](http://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html)。 – axiac

+0

Thx再次爲答案所以如果我喜歡使用'pcntl_signal_dispatch'而不是'ticks = 1',那麼我必須在哪裏調用它?在我的循環中的某個地方?然後腳本被執行到我猜想的調度調用,然後調用'pcntl_signal'函數定義的回調函數 – TiMESPLiNTER

0

這可能有一些非常有用的信息,看起來他們正在利用你嘗試過的相同的東西,但看起來有積極的結果?也許這裏有一些你沒有嘗試或者錯過的東西。

Automatically Restart PHP Script on Exit