Starten Sie einen CLI-Prozess neu, ohne die Xdebug-Erweiterung zu laden, es sei denn xdebug.mode=off
.
Ursprünglich als Teil von Composer/Composer geschrieben, jetzt extrahiert und als eigenständige Bibliothek verfügbar gemacht.
Die Unterstützung für ältere PHP-Versionen wurde entfernt und Typdeklarationen hinzugefügt.
Die langfristige Unterstützung für Version 2 (PHP 5.3.2 – 7.2.4) folgt der Composer 2.2 LTS-Richtlinie.
Installieren Sie die neueste Version mit:
$ composer require composer/xdebug-handler
use Composer XdebugHandler XdebugHandler ;
$ xdebug = new XdebugHandler ( ' myapp ' );
$ xdebug -> check ();
unset( $ xdebug );
Der Konstruktor verwendet einen einzelnen Parameter, $envPrefix
, der in Großbuchstaben geschrieben und den Standardbasiswerten vorangestellt wird, um zwei unterschiedliche Umgebungsvariablen zu erstellen. Das obige Beispiel ermöglicht die Verwendung von:
MYAPP_ALLOW_XDEBUG=1
um den automatischen Neustart zu überschreiben und Xdebug zuzulassenMYAPP_ORIGINAL_INIS
um die Speicherorte der INI-Dateien in einem neu gestarteten Prozess abzurufen Aus den geladenen (und gescannten) INI-Dateien wird eine temporäre INI-Datei erstellt, wobei alle Verweise auf die Xdebug-Erweiterung auskommentiert sind. Aktuelle INI-Einstellungen werden zusammengeführt, sodass die meisten in der Befehlszeile oder von der Anwendung vorgenommenen INI-Einstellungen enthalten sind (siehe Einschränkungen).
MYAPP_ALLOW_XDEBUG
wird mit internen Daten zur Kennzeichnung und Verwendung beim Neustart festgelegt.MYAPP_ALLOW_XDEBUG
ist nicht gesetzt.Weitere Informationen finden Sie unter Beispiele.
Die asynchrone Signalverarbeitung wird automatisch aktiviert, wenn die pcntl-Erweiterung geladen ist. SIGINT
wird im übergeordneten Prozess auf SIG_IGN
gesetzt und im neu gestarteten Prozess auf SIG_DFL
wiederhergestellt (sofern kein anderer Handler festgelegt wurde).
Ab PHP 7.4 unter Windows wird die Handhabung von CTRL+C
und CTRL+BREAK
im neu gestarteten Prozess automatisch aktiviert und im übergeordneten Prozess ignoriert.
Bei der Ausführung innerhalb eines neu gestarteten Prozesses sind einige Dinge zu beachten.
Diese statischen Methoden liefern Informationen aus dem aktuellen Prozess, unabhängig davon, ob dieser neu gestartet wurde oder nicht.
Gibt ein Array der ursprünglichen Speicherorte der INI-Dateien zurück. Verwenden Sie dies, anstatt php_ini_loaded_file
und php_ini_scanned_files
aufzurufen, die bei einem neu gestarteten Prozess die falschen Werte melden.
use Composer XdebugHandler XdebugHandler ;
$ files = XdebugHandler:: getAllIniFiles ();
# $ files [ 0 ] always exists , it could be an empty string
$ loadedIni = array_shift ( $ files );
$ scannedInis = $ files ;
Diese Speicherorte sind auch in der Umgebungsvariablen MYAPP_ORIGINAL_INIS
verfügbar. Dies ist eine durch Pfade getrennte Zeichenfolge, die den von php_ini_loaded_file
zurückgegebenen Speicherort enthält, der leer sein kann, gefolgt von Speicherorten, die beim Aufruf von php_ini_scanned_files
analysiert wurden.
Gibt ein Array von Einstellungen zurück, die mit PHP-Unterprozessen verwendet werden können, oder null, wenn der Prozess nicht neu gestartet wurde.
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 )
*/
Gibt die Xdebug-Versionszeichenfolge zurück, die beim Neustart übersprungen wurde, oder eine leere Zeichenfolge, wenn kein Neustart stattgefunden hat (oder Xdebug immer noch geladen ist, möglicherweise durch einen Neustart einer Erweiterungsklasse aus einem anderen Grund als dem Entfernen von Xdebug).
use Composer XdebugHandler XdebugHandler ;
$ version = XdebugHandler:: getSkippedVersion ();
# $version : ' 3.1 . 1 ' ( for example ) , or an empty string
Gibt „true“ zurück, wenn Xdebug geladen ist und in einem aktiven Modus ausgeführt wird (sofern es Modi unterstützt). Gibt false zurück, wenn Xdebug nicht geladen ist oder mit xdebug.mode=off
ausgeführt wird.
Diese Methoden implementieren eine fließende Schnittstelle und müssen vor der Hauptmethode check()
aufgerufen werden.
Ermöglicht die Ausgabe von Statusmeldungen an einen externen PSR3-Logger. Alle Meldungen werden entweder mit den Protokollebenen DEBUG
oder WARNING
gemeldet. Zum Beispiel (Anzeige des Levels und der Nachricht):
// 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: ...)
Statusmeldungen können auch mit XDEBUG_HANDLER_DEBUG
ausgegeben werden. Siehe Fehlerbehebung.
Legt den Speicherort des Hauptskripts fest, das beim Neustart ausgeführt werden soll. Dies ist nur in esoterischeren Anwendungsfällen erforderlich oder wenn auf den Speicherort argv[0]
nicht zugegriffen werden kann. Der Skriptname --
wird für die Standardeingabe unterstützt.
Konfiguriert den Neustart mithilfe persistenter Einstellungen, sodass Xdebug nicht in einen Unterprozess geladen wird.
Verwenden Sie diese Methode, wenn Ihre Anwendung einen oder mehrere PHP-Unterprozesse aufruft und die Xdebug-Erweiterung nicht benötigt wird. Dadurch wird der Aufwand für die Implementierung spezifischer Teilprozessstrategien vermieden.
Alternativ kann diese Methode verwendet werden, um eine Xdebug-freie Standardumgebung einzurichten, die geändert werden kann, wenn ein Unterprozess Xdebug erfordert, und anschließend wiederhergestellt werden kann:
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 ();
}
Die Bibliothek bietet zwei Strategien zum Aufrufen eines neuen PHP-Prozesses, ohne Xdebug zu laden, indem sie entweder Standard- oder persistente Einstellungen verwendet. Beachten Sie, dass dies nur wichtig ist, wenn die Anwendung einen PHP-Unterprozess aufruft.
Verwendet Befehlszeilenoptionen, um Xdebug nur aus dem neuen Prozess zu entfernen.
Wenn der neue Prozess einen PHP-Unterprozess aufruft, wird Xdebug in diesen Unterprozess geladen (es sei denn, er implementiert den xdebug-handler; in diesem Fall erfolgt ein weiterer Neustart).
Dies ist die Standardstrategie, die beim Neustart verwendet wird.
Verwendet Umgebungsvariablen, um Xdebug aus dem neuen Prozess zu entfernen und diese Einstellungen in jedem Unterprozess beizubehalten.
PHP_INI_SCAN_DIR
ist auf eine leere Zeichenfolge gesetzt. Dadurch wird PHP angewiesen, nicht nach zusätzlichen Inis zu suchen.PHPRC
ist auf die temporäre INI gesetzt.Wenn der neue Prozess einen PHP-Unterprozess aufruft, wird Xdebug nicht in diesen Unterprozess geladen.
Diese Strategie kann beim Neustart durch Aufruf von setPersistent() verwendet werden.
Die Hilfsklasse PhpConfig
erleichtert das Aufrufen eines PHP-Unterprozesses (mit oder ohne geladenem Xdebug), unabhängig davon, ob ein Neustart stattgefunden hat.
Jede seiner Methoden gibt ein Array von PHP-Optionen zurück (zum Hinzufügen zur Befehlszeile) und richtet die Umgebung für die erforderliche Strategie ein. Die Methode getRestartSettings() wird intern verwendet.
useOriginal()
– Xdebug wird im neuen Prozess geladen.useStandard()
– Xdebug wird im neuen Prozess nicht geladen – siehe Standardeinstellungen.userPersistent()
– Xdebug wird nicht in den neuen Prozess geladen – siehe persistente EinstellungenWenn kein Neustart stattgefunden hat, wird ein leeres Optionsarray zurückgegeben und die Umgebung wird nicht geändert.
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 = ''
Die folgenden Umgebungseinstellungen können zur Fehlerbehebung bei unerwartetem Verhalten verwendet werden:
XDEBUG_HANDLER_DEBUG=1
Gibt Statusmeldungen an STDERR
aus, sofern definiert, unabhängig von einem PSR3-Logger. Jeder Nachricht wird xdebug-handler[pid]
vorangestellt, wobei pid die Prozesskennung ist.
XDEBUG_HANDLER_DEBUG=2
Wie oben, speichert aber zusätzlich die temporäre INI-Datei und meldet deren Speicherort in einer Statusmeldung.
Die API wird durch Klassen und ihre zugänglichen Elemente definiert, die nicht als @internal annotiert sind. Die Hauptklasse verfügt über zwei geschützte Methoden, die überschrieben werden können, um zusätzliche Funktionalität bereitzustellen:
Standardmäßig wird der Prozess neu gestartet, wenn Xdebug geladen ist und nicht mit xdebug.mode=off
ausgeführt wird. Durch die Erweiterung dieser Methode kann eine Anwendung entscheiden, indem sie einen booleschen Wert (oder einen gleichwertigen Wert) zurückgibt. Es wird nur aufgerufen, wenn MYAPP_ALLOW_XDEBUG
leer ist, daher wird es nicht im neu gestarteten Prozess aufgerufen (wo diese Variable interne Daten enthält) oder wenn der Neustart überschrieben wurde.
Beachten Sie, dass hier bei Bedarf die Setter setMainScript() und setPersistent() verwendet werden können.
Eine Anwendung kann dies erweitern, um die temporäre INI-Datei zu ändern, deren Speicherort in der Eigenschaft tmpIni
angegeben ist. Neue Einstellungen können sicher an das Ende der Daten angehängt werden, das mit PHP_EOL
beendet wird.
Der Parameter $command
ist ein Array von Befehlszeilenargumenten ohne Escapezeichen, die für den neuen Prozess verwendet werden.
Denken Sie daran, mit parent::restart($command)
abzuschließen.
Dieses Beispiel zeigt zwei Möglichkeiten zur Erweiterung der Grundfunktionalität:
Um den Aufwand für das Hochfahren eines neuen Prozesses zu vermeiden, wird der Neustart übersprungen, wenn ein einfacher Hilfebefehl angefordert wird.
Die Anwendung benötigt Schreibzugriff auf Phar-Dateien und erzwingt daher einen Neustart, wenn phar.readonly
festgelegt ist (unabhängig davon, ob Xdebug geladen ist) und ändert diesen Wert in der temporären INI-Datei.
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 );
}
}
Das Verzeichnis testsApp
enthält Befehlszeilenskripts, die die internen Abläufe in verschiedenen Szenarien demonstrieren. Siehe Funktionstestskripte.
Composer/xdebug-handler ist unter der MIT-Lizenz lizenziert. Weitere Informationen finden Sie in der LICENSE-Datei.