2024 年 PHP Conference Japan

簡介

PHP 中的流程控制支援採用 Unix 風格的流程建立、程式執行、訊號處理和流程終止。流程控制不應在網路伺服器環境中啟用,如果在網路伺服器環境中使用任何流程控制函式,可能會產生意外結果。

本文旨在說明每個流程控制函式的一般用法。有關 Unix 流程控制的詳細資訊,建議您參考系統文件,包括 fork(2)、waitpid(2) 和 signal(2),或參考 W. Richard Stevens(Addison-Wesley)所著的《Unix 環境進階程式設計》等綜合參考書籍。

PCNTL 現在使用「刻度」(ticks) 作為訊號處理的回呼機制,這比以前的機制快得多。此變更遵循與使用「使用者刻度」相同的語義。您可以使用 declare() 陳述式來指定程式中允許回呼發生的位置。這讓您可以最小化處理非同步事件的額外負擔。過去,編譯啟用 pcntl 的 PHP 總是會產生這種額外負擔,無論您的腳本是否實際使用 pcntl。

注意此擴充功能在 Windows 平台上無法使用。

新增註釋

使用者貢獻的註釋 3 則註釋

sean dot kelly at mediatile dot com
12 年前
以下的陳述讓我搜尋答案大約一天,才終於弄明白

「不應在網路伺服器環境中啟用行程控制,如果在網路伺服器環境中使用任何行程控制函式,可能會發生非預期的結果。」

至少對於我正在使用的 PHP 5.3.8 以及更早的版本來說,這不是「不應」的問題,而是「不能」的問題。即使我已經使用 --enable-pcntl 編譯了 PCNTL,結果它只編譯到 CLI 版本的 PHP 中,而不是 Apache 模組中。因此,我花了許多時間試圖找出為什麼 function_exists('pcntl_fork') 會返回 false,即使它編譯正確。結果發現,從 CLI 執行時它會正確地返回 true,而只有在處理 HTTP 請求時才會返回 false。所有 pcntl_*() 函式都是如此。
InvisibleSmiley
4 年前
停用 pcntl 函式不僅會影響 Apache 伺服器,還會影響任何非 CLI 的設定,例如使用 PHP-FPM 的 nginx。

您可以透過執行 phpinfo() 並查看輸出中「核心」區段的「disable_functions」來判斷。

還值得注意的是,當您在命名空間的上下文中呼叫其中一個 pcntl 函式時,這種行為可能會造成誤導。例如,您可能會收到

「呼叫了未定義的函式 some\custom\namespace\pcntl_signal()」

當從命名空間類別中的方法呼叫 pcntl_signal 時。您的第一直覺可能是新增一個反斜線,但这並不能解決問題。您需要檢查函式在執行階段是否存在,除非程式碼只從 CLI 執行。
Rick Sustek
8 年前
實際上,Apache 模組不支援行程控制功能的原因非常合理。Apache HTTP 伺服器是主要的行程。當被請求的資源導向 PHP 時(例如 http://foo.php),它會呼叫 PHP 模組。它通常會在新執行緒或共用執行緒池中呼叫 PHP 模組。然後 PHP 模組會執行您的腳本,但 Apache 伺服器仍然是擁有行程。

在這種執行模型中,您的 PHP 腳本的工作通常是盡快完成其任務並返回。這允許 Apache 常駐程式使用它借給您的線程去做其他有用的事情。是的,有些腳本執行任務所需的時間比其他腳本長,但長時間阻塞線程通常是不被允許的。

如果允許您的腳本干擾正在運行的程序的信號處理程序,它將會干擾 Apache 常駐程式本身!該常駐程式已經安裝了供自己使用的信號處理程序。在這種情況下不允許程序控制操作是很合理的。
To Top