Reinicie un proceso CLI sin cargar la extensión Xdebug, a menos que xdebug.mode=off
.
Originalmente escrito como parte de compositor/compositor, ahora extraído y disponible como una biblioteca independiente.
Se eliminó la compatibilidad con versiones heredadas de PHP y se agregaron declaraciones de tipos.
El soporte a largo plazo para la versión 2 (PHP 5.3.2 - 7.2.4) sigue la política de Composer 2.2 LTS.
Instale la última versión con:
$ composer require composer/xdebug-handler
use Composer XdebugHandler XdebugHandler ;
$ xdebug = new XdebugHandler ( ' myapp ' );
$ xdebug -> check ();
unset( $ xdebug );
El constructor toma un único parámetro, $envPrefix
, que está en mayúsculas y antepuesto a los valores base predeterminados para crear dos variables de entorno distintas. El ejemplo anterior permite el uso de:
MYAPP_ALLOW_XDEBUG=1
para anular el reinicio automático y permitir XdebugMYAPP_ORIGINAL_INIS
para obtener ubicaciones de archivos ini en un proceso reiniciado Se crea un archivo ini temporal a partir de los archivos ini cargados (y escaneados), con cualquier referencia a la extensión Xdebug comentada. La configuración de ini actual se fusiona, de modo que se incluyen la mayoría de las configuraciones de ini realizadas en la línea de comandos o mediante la aplicación (consulte Limitaciones)
MYAPP_ALLOW_XDEBUG
está configurado con datos internos para marcar y usar en el reinicio.MYAPP_ALLOW_XDEBUG
no está configurado.Consulte Ejemplos para obtener más información.
El manejo de señales asíncrono se habilita automáticamente si se carga la extensión pcntl. SIGINT
se establece en SIG_IGN
en el proceso principal y se restaura en SIG_DFL
en el proceso reiniciado (si no se ha configurado ningún otro controlador).
Desde PHP 7.4 en Windows, el manejo CTRL+C
y CTRL+BREAK
se habilita automáticamente en el proceso reiniciado y se ignora en el proceso principal.
Hay algunas cosas que se deben tener en cuenta cuando se ejecuta dentro de un proceso reiniciado.
Estos métodos estáticos proporcionan información del proceso actual, independientemente de si se ha reiniciado o no.
Devuelve una matriz de las ubicaciones del archivo ini original. Utilice esto en lugar de llamar php_ini_loaded_file
y php_ini_scanned_files
, que informarán valores incorrectos en un proceso reiniciado.
use Composer XdebugHandler XdebugHandler ;
$ files = XdebugHandler:: getAllIniFiles ();
# $ files [ 0 ] always exists , it could be an empty string
$ loadedIni = array_shift ( $ files );
$ scannedInis = $ files ;
Estas ubicaciones también están disponibles en la variable de entorno MYAPP_ORIGINAL_INIS
. Esta es una cadena separada por ruta que comprende la ubicación devuelta por php_ini_loaded_file
, que podría estar vacía, seguida de las ubicaciones analizadas al llamar a php_ini_scanned_files
.
Devuelve una serie de configuraciones que se pueden usar con subprocesos PHP, o nulas si el proceso no se reinició.
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 )
*/
Devuelve la cadena de la versión de Xdebug que se omitió durante el reinicio, o una cadena vacía si no hubo reinicio (o Xdebug todavía está cargado, tal vez porque una clase extendida se reinicia por un motivo distinto a la eliminación de Xdebug).
use Composer XdebugHandler XdebugHandler ;
$ version = XdebugHandler:: getSkippedVersion ();
# $version : ' 3.1 . 1 ' ( for example ) , or an empty string
Devuelve verdadero si Xdebug está cargado y se ejecuta en modo activo (si admite modos). Devuelve false si Xdebug no está cargado o se está ejecutando con xdebug.mode=off
.
Estos métodos implementan una interfaz fluida y deben llamarse antes del método check()
principal.
Permite la salida de mensajes de estado a un registrador PSR3 externo. Todos los mensajes se informan con niveles de registro DEBUG
o WARNING
. Por ejemplo (mostrando el nivel y el mensaje):
// 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: ...)
Los mensajes de estado también se pueden generar con XDEBUG_HANDLER_DEBUG
. Consulte Solución de problemas.
Establece la ubicación del script principal para ejecutarse en el reinicio. Esto solo es necesario en casos de uso más esotéricos o si la ubicación argv[0]
es inaccesible. El nombre del script --
compatible con la entrada estándar.
Configura el reinicio usando configuraciones persistentes, para que Xdebug no se cargue en ningún subproceso.
Utilice este método si su aplicación invoca uno o más subprocesos PHP y no necesita la extensión Xdebug. Esto evita la sobrecarga de implementar estrategias de subprocesos específicas.
Alternativamente, este método se puede utilizar para configurar un entorno libre de Xdebug predeterminado que se puede cambiar si un subproceso requiere Xdebug y luego restaurarlo:
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 ();
}
La biblioteca ofrece dos estrategias para invocar un nuevo proceso PHP sin cargar Xdebug, utilizando configuraciones estándar o persistentes . Tenga en cuenta que esto sólo es importante si la aplicación llama a un subproceso PHP.
Utiliza opciones de línea de comandos para eliminar Xdebug únicamente del nuevo proceso.
Si el nuevo proceso llama a un subproceso PHP, Xdebug se cargará en ese subproceso (a menos que implemente xdebug-handler, en cuyo caso habrá otro reinicio).
Esta es la estrategia predeterminada utilizada en el reinicio.
Utiliza variables de entorno para eliminar Xdebug del nuevo proceso y conservar estas configuraciones en cualquier subproceso.
PHP_INI_SCAN_DIR
está configurado como una cadena vacía. Esto le dice a PHP que no busque inis adicionales.PHPRC
está configurado en el ini temporal.Si el nuevo proceso llama a un subproceso PHP, Xdebug no se cargará en ese subproceso.
Esta estrategia se puede utilizar en el reinicio llamando a setPersistent().
La clase auxiliar PhpConfig
facilita la invocación de un subproceso PHP (con o sin Xdebug cargado), independientemente de si se ha reiniciado.
Cada uno de sus métodos devuelve una serie de opciones de PHP (para agregar a la línea de comandos) y configura el entorno para la estrategia requerida. El método getRestartSettings() se utiliza internamente.
useOriginal()
: Xdebug se cargará en el nuevo proceso.useStandard()
: Xdebug no se cargará en el nuevo proceso; consulte la configuración estándar.userPersistent()
- Xdebug no se cargará en el nuevo proceso - consulte la configuración persistenteSi no hubo reinicio, se devuelve una matriz de opciones vacía y el entorno no cambia.
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 = ''
Se pueden utilizar las siguientes configuraciones de entorno para solucionar problemas de comportamiento inesperado:
XDEBUG_HANDLER_DEBUG=1
Envía mensajes de estado a STDERR
, si está definido, independientemente de cualquier registrador PSR3. Cada mensaje tiene el prefijo xdebug-handler[pid]
, donde pid es el identificador del proceso.
XDEBUG_HANDLER_DEBUG=2
Como arriba, pero además guarda el archivo ini temporal e informa su ubicación en un mensaje de estado.
La API está definida por clases y sus elementos accesibles que no están anotados como @internal. La clase principal tiene dos métodos protegidos que se pueden anular para proporcionar funcionalidad adicional:
De forma predeterminada, el proceso se reiniciará si Xdebug está cargado y no se ejecuta con xdebug.mode=off
. Ampliar este método permite que una aplicación decida devolviendo un valor booleano (o equivalente). Solo se llama si MYAPP_ALLOW_XDEBUG
está vacío, por lo que no se llamará en el proceso reiniciado (donde esta variable contiene datos internos) o si se anuló el reinicio.
Tenga en cuenta que los configuradores setMainScript() y setPersistent() se pueden utilizar aquí, si es necesario.
Una aplicación puede ampliar esto para modificar el archivo ini temporal, cuya ubicación se proporciona en la propiedad tmpIni
. Se pueden agregar nuevas configuraciones de forma segura al final de los datos, que terminan en PHP_EOL
.
El parámetro $command
es una matriz de argumentos de línea de comandos sin escape que se utilizarán para el nuevo proceso.
Recuerde terminar con parent::restart($command)
.
Este ejemplo demuestra dos formas de ampliar la funcionalidad básica:
Para evitar la sobrecarga de iniciar un nuevo proceso, se omite el reinicio si se solicita un comando de ayuda simple.
La aplicación necesita acceso de escritura a los archivos phar, por lo que forzará un reinicio si se establece phar.readonly
(independientemente de si Xdebug está cargado) y cambiará este valor en el archivo ini temporal.
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 );
}
}
El directorio testsApp
contiene scripts de línea de comandos que demuestran el funcionamiento interno en una variedad de escenarios. Consulte Scripts de prueba funcional.
Composer/xdebug-handler tiene la licencia MIT; consulte el archivo LICENCIA para obtener más detalles.