重新啟動 CLI 程序而不載入 Xdebug 擴展,除非xdebug.mode=off
。
最初是作為作曲家/作曲家的一部分編寫的,現在提取並作為獨立庫提供。
刪除了對舊 PHP 版本的支援並新增了類型聲明。
對版本 2 (PHP 5.3.2 - 7.2.4) 的長期支持遵循 Composer 2.2 LTS 政策。
安裝最新版本:
$ composer require composer/xdebug-handler
use Composer XdebugHandler XdebugHandler ;
$ xdebug = new XdebugHandler ( ' myapp ' );
$ xdebug -> check ();
unset( $ xdebug );
建構函式採用單一參數$envPrefix
,該參數為大寫並加入預設基底值之前,以建立兩個不同的環境變數。上面的範例允許使用:
MYAPP_ALLOW_XDEBUG=1
覆寫自動重新啟動並允許 XdebugMYAPP_ORIGINAL_INIS
用於取得重新啟動的進程中的 ini 檔案位置從載入(和掃描)的 ini 檔案建立臨時 ini 文件,並註解掉對 Xdebug 副檔名的任何參考。目前的 ini 設定被合併,以便包含在命令列或應用程式中進行的大多數 ini 設定(請參閱限制)
MYAPP_ALLOW_XDEBUG
使用內部資料進行設置,以在重新啟動時進行標記和使用。MYAPP_ALLOW_XDEBUG
未設定。請參閱範例以取得更多資訊。
如果載入了 pcntl 擴展,則會自動啟用非同步訊號處理。 SIGINT
在父進程中設定為SIG_IGN
,並在重新啟動的進程中恢復為SIG_DFL
(如果未設定其他處理程序)。
從 Windows 上的 PHP 7.4 開始, CTRL+C
和CTRL+BREAK
處理會在重新啟動的進程中自動啟用,並在父進程中被忽略。
在重新啟動的進程中執行時需要注意一些事項。
這些靜態方法提供當前進程的信息,無論它是否已重新啟動。
傳回原始 ini 檔案位置的陣列。使用它而不是呼叫php_ini_loaded_file
和php_ini_scanned_files
,這將在重新啟動的進程中報告錯誤的值。
use Composer XdebugHandler XdebugHandler ;
$ files = XdebugHandler:: getAllIniFiles ();
# $ files [ 0 ] always exists , it could be an empty string
$ loadedIni = array_shift ( $ files );
$ scannedInis = $ files ;
這些位置也可在MYAPP_ORIGINAL_INIS
環境變數中找到。這是一個路徑分隔的字串,包含從php_ini_loaded_file
返回的位置(可以為空),後面是透過呼叫php_ini_scanned_files
解析的位置。
傳回可與 PHP 子進程一起使用的設定數組,如果進程未重新啟動,則傳回 null。
use Composer XdebugHandler XdebugHandler ;
$ settings = XdebugHandler:: getRestartSettings ();
/**
* $ settings : array ( if the current process was restarted ,
* or called with the settings from a previous restart ) , or null
*
* ' tmp Ini ' = > the temporary ini file used in the restart ( string )
* ' scanned Inis ' = > if there were any scanned inis ( bool )
* ' scan Dir ' = > the original PHP _ INI _ SCAN _ DIR value ( false |string )
* ' phprc ' = > the original PHPRC value ( false |string )
* ' inis ' = > the original inis from get AllIniFiles ( array )
* ' skipped ' = > the skipped version from get SkippedVersion ( string )
*/
返回重新啟動時跳過的 Xdebug 版本字串,如果沒有重新啟動,則返回空字串(或者 Xdebug 仍然加載,可能是由於擴展類別由於刪除 Xdebug 之外的原因重新啟動)。
use Composer XdebugHandler XdebugHandler ;
$ version = XdebugHandler:: getSkippedVersion ();
# $version : ' 3.1 . 1 ' ( for example ) , or an empty string
如果 Xdebug 已載入並在活動模式下運行(如果它支援模式),則傳回 true。如果 Xdebug 未加載,或以xdebug.mode=off
運行,則傳回 false。
這些方法實作了一個流暢的接口,並且必須在主check()
方法之前呼叫。
允許將狀態訊息輸出到外部 PSR3 記錄器。所有訊息均以DEBUG
或WARNING
日誌等級報告。例如(顯示等級和訊息):
// No restart
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.1) xdebug.mode=off
DEBUG No restart (APP_ALLOW_XDEBUG=0) Allowed by xdebug.mode
// Restart overridden
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.1) xdebug.mode=coverage,debug,develop
DEBUG No restart (MYAPP_ALLOW_XDEBUG=1)
// Failed restart
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.0)
WARNING No restart (Unable to create temp ini file at: ...)
狀態訊息也可以使用XDEBUG_HANDLER_DEBUG
輸出。請參閱故障排除。
設定重新啟動時運行的主腳本的位置。僅在更深奧的用例中,或argv[0]
位置不可存取時才需要這樣做。標準輸入支援腳本--
。
使用持久性設定配置重新啟動,以便 Xdebug 不會在任何子進程中載入。
如果您的應用程式呼叫一個或多個 PHP 子進程並且不需要 Xdebug 擴展,請使用此方法。這避免了實施特定子流程策略的開銷。
或者,此方法可用於設定預設的無 Xdebug環境,如果子程序需要 Xdebug,則可以變更該環境,然後還原:
function SubProcessWithXdebug ()
{
$ phpConfig = new Composer XdebugHandler PhpConfig ();
# Set the environment to the original configuration
$ phpConfig -> useOriginal ();
# run the process with Xdebug loaded
. . .
# Restore Xdebug - free environment
$ phpConfig -> usePersistent ();
}
該程式庫提供了兩種策略來呼叫新的 PHP 進程而不載入 Xdebug,使用標準或持久性設定。請注意,這僅在應用程式呼叫 PHP 子進程時才重要。
使用命令列選項僅從新進程中刪除 Xdebug。
如果新進程呼叫 PHP 子進程,Xdebug 將在該子進程中載入(除非它實作了 xdebug-handler,在這種情況下將再次重新啟動)。
這是重啟時使用的預設策略。
使用環境變數從新進程中刪除 Xdebug 並將這些設定保留到任何子進程。
PHP_INI_SCAN_DIR
設定為空字串。這告訴 PHP 不要掃描額外的 inis。PHPRC
設定為臨時 ini。如果新進程呼叫 PHP 子進程,則 Xdebug 將不會載入到該子進程中。
該策略可以透過呼叫setPersistent()在重啟時使用。
PhpConfig
幫助程式類別可以輕鬆呼叫 PHP 子進程(載入或不載入 Xdebug),無論是否重新啟動。
它的每個方法都會傳回一組 PHP 選項(新增至命令列)並為所需策略設定環境。 getRestartSettings() 方法在內部使用。
useOriginal()
- Xdebug 將在新進程中載入。useStandard()
- Xdebug不會在新進程中載入 - 請參閱標準設定。userPersistent()
- Xdebug不會在新進程中載入 - 請參閱持久性設定如果沒有重新啟動,則會傳回一個空選項數組,且環境不會變更。
use Composer XdebugHandler PhpConfig ;
$ config = new PhpConfig ;
$ options = $ config -> useOriginal ();
# $options : empty array
# environment : PHPRC and PHP _ INI _ SCAN _ DIR set to original values
$ options = $ config -> useStandard ();
# $options : [ - n , - c , tmp Ini ]
# environment : PHPRC and PHP _ INI _ SCAN _ DIR set to original values
$ options = $ config -> usePersistent ();
# $options : empty array
# environment : PHPRC = tmpIni , PHP_INI_SCAN_DIR = ''
以下環境設定可用於解決意外行為:
XDEBUG_HANDLER_DEBUG=1
將狀態訊息輸出到STDERR
(如果已定義),無論任何 PSR3 記錄器如何。每個訊息都有前綴xdebug-handler[pid]
,其中 pid 是進程標識符。
XDEBUG_HANDLER_DEBUG=2
如上所述,但另外保存臨時 ini 檔案並在狀態訊息中報告其位置。
API 由類別及其可存取元素定義,這些元素未註釋為 @internal。主類別有兩個受保護的方法,可以重寫它們以提供附加功能:
預設情況下,如果 Xdebug 已載入且未使用xdebug.mode=off
執行,則進程將重新啟動。擴展此方法允許應用程式透過返回布林(或等效)值來做出決定。只有當MYAPP_ALLOW_XDEBUG
為空時才會呼叫它,因此在重新啟動的進程中(其中變數包含內部資料)或重新啟動已被覆寫時不會呼叫它。
請注意,如果需要,可以在此處使用 setMainScript() 和 setPersistent() 設定器。
應用程式可以擴展它來修改臨時 ini 文件,其位置在tmpIni
屬性中給出。新設定可以安全地附加到資料末尾,即PHP_EOL
終止。
$command
參數是將用於新進程的未轉義命令列參數的陣列。
記得以parent::restart($command)
結束。
此範例示範了擴展基本功能的兩種方法:
為了避免啟動新進程的開銷,如果請求簡單的幫助命令,則會跳過重新啟動。
應用程式需要對 phar 檔案進行寫入訪問,因此如果設定了phar.readonly
(無論是否載入 Xdebug)並在臨時 ini 檔案中更改此值,它將強制重新啟動。
use Composer XdebugHandler XdebugHandler ;
use MyApp Command ;
class MyRestarter extends XdebugHandler
{
private $ required ;
protected function requiresRestart ( bool $ default ): bool
{
if (Command:: isHelp ()) {
# No need to disable Xdebug for this
return false ;
}
$ this -> required = ( bool ) ini_get ( ' phar.readonly ' );
return $ this -> required || $ default ;
}
protected function restart ( array $ command ): void
{
if ( $ this -> required ) {
# Add required ini setting to tmp Ini
$ content = file_get_contents ( $ this -> tmpIni );
$ content .= ' phar.readonly=0 ' . PHP_EOL ;
file_put_contents ( $ this -> tmpIni , $ content );
}
parent :: restart ( $ command );
}
}
testsApp
目錄包含命令列腳本,可示範各種場景下的內部運作原理。請參閱功能測試腳本。
composer/xdebug-handler 根據 MIT 許可證獲得許可,有關詳細信息,請參閱許可證文件。