Reinicie um processo CLI sem carregar a extensão Xdebug, a menos que xdebug.mode=off
.
Originalmente escrito como parte do compositor/compositor, agora extraído e disponibilizado como uma biblioteca independente.
Removido o suporte para versões legadas do PHP e adicionadas declarações de tipo.
O suporte de longo prazo para a versão 2 (PHP 5.3.2 - 7.2.4) segue a política LTS do Composer 2.2.
Instale a versão mais recente com:
$ composer require composer/xdebug-handler
use Composer XdebugHandler XdebugHandler ;
$ xdebug = new XdebugHandler ( ' myapp ' );
$ xdebug -> check ();
unset( $ xdebug );
O construtor usa um único parâmetro, $envPrefix
, que é maiúsculo e anexado aos valores base padrão para criar duas variáveis de ambiente distintas. O exemplo acima permite o uso de:
MYAPP_ALLOW_XDEBUG=1
para substituir a reinicialização automática e permitir o XdebugMYAPP_ORIGINAL_INIS
para obter locais de arquivos ini em um processo reiniciado Um arquivo ini temporário é criado a partir dos arquivos ini carregados (e verificados), com quaisquer referências à extensão Xdebug comentadas. As configurações ini atuais são mescladas, de modo que a maioria das configurações ini feitas na linha de comando ou pelo aplicativo sejam incluídas (consulte Limitações)
MYAPP_ALLOW_XDEBUG
é definido com dados internos para sinalizar e usar na reinicialização.MYAPP_ALLOW_XDEBUG
não está definido.Consulte Exemplos para obter mais informações.
O tratamento de sinal assíncrono é ativado automaticamente se a extensão pcntl for carregada. SIGINT
é definido como SIG_IGN
no processo pai e restaurado para SIG_DFL
no processo reiniciado (se nenhum outro manipulador tiver sido definido).
A partir do PHP 7.4 no Windows, a manipulação de CTRL+C
e CTRL+BREAK
é automaticamente habilitada no processo reiniciado e ignorada no processo pai.
Há algumas coisas que você deve saber ao executar dentro de um processo reiniciado.
Esses métodos estáticos fornecem informações do processo atual, independentemente de ele ter sido reiniciado ou não.
Retorna uma matriz dos locais originais do arquivo ini. Use isto em vez de chamar php_ini_loaded_file
e php_ini_scanned_files
, que reportará os valores errados em um processo reiniciado.
use Composer XdebugHandler XdebugHandler ;
$ files = XdebugHandler:: getAllIniFiles ();
# $ files [ 0 ] always exists , it could be an empty string
$ loadedIni = array_shift ( $ files );
$ scannedInis = $ files ;
Esses locais também estão disponíveis na variável de ambiente MYAPP_ORIGINAL_INIS
. Esta é uma string separada por caminho que compreende o local retornado de php_ini_loaded_file
, que pode estar vazio, seguido por locais analisados pela chamada de php_ini_scanned_files
.
Retorna um array de configurações que podem ser usadas com subprocessos PHP, ou null se o processo não foi reiniciado.
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 )
*/
Retorna a string da versão do Xdebug que foi ignorada pela reinicialização ou uma string vazia se não houve reinicialização (ou o Xdebug ainda está carregado, talvez por uma classe de extensão reiniciando por um motivo diferente da remoção do Xdebug).
use Composer XdebugHandler XdebugHandler ;
$ version = XdebugHandler:: getSkippedVersion ();
# $version : ' 3.1 . 1 ' ( for example ) , or an empty string
Retorna verdadeiro se o Xdebug estiver carregado e em execução em modo ativo (se suportar modos). Retorna false se o Xdebug não estiver carregado ou estiver sendo executado com xdebug.mode=off
.
Esses métodos implementam uma interface fluente e devem ser chamados antes do método check()
principal.
Permite a saída de mensagens de status para um registrador PSR3 externo. Todas as mensagens são relatadas com níveis de log DEBUG
ou WARNING
. Por exemplo (mostrando o nível e a mensagem):
// 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: ...)
Mensagens de status também podem ser emitidas com XDEBUG_HANDLER_DEBUG
. Consulte Solução de problemas.
Define o local do script principal a ser executado na reinicialização. Isso só é necessário em casos de uso mais esotéricos ou se o local argv[0]
estiver inacessível. O nome do script --
é compatível com entrada padrão.
Configura a reinicialização usando configurações persistentes, para que o Xdebug não seja carregado em nenhum subprocesso.
Use este método se seu aplicativo invocar um ou mais subprocessos PHP e a extensão Xdebug não for necessária. Isso evita a sobrecarga de implementação de estratégias específicas de subprocessos.
Alternativamente, este método pode ser usado para configurar um ambiente padrão livre de Xdebug que pode ser alterado se um subprocesso exigir Xdebug e depois restaurado:
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 ();
}
A biblioteca oferece duas estratégias para invocar um novo processo PHP sem carregar o Xdebug, usando configurações padrão ou persistentes . Observe que isso só é importante se o aplicativo chamar um subprocesso PHP.
Usa opções de linha de comando para remover o Xdebug apenas do novo processo.
Se o novo processo chamar um subprocesso PHP, o Xdebug será carregado nesse subprocesso (a menos que implemente o xdebug-handler, caso em que haverá outra reinicialização).
Esta é a estratégia padrão usada na reinicialização.
Usa variáveis de ambiente para remover o Xdebug do novo processo e persistir essas configurações em qualquer subprocesso.
PHP_INI_SCAN_DIR
é definido como uma string vazia. Isso diz ao PHP para não procurar inis adicionais.PHPRC
está configurado para o ini temporário.Se o novo processo chamar um subprocesso PHP, o Xdebug não será carregado nesse subprocesso.
Esta estratégia pode ser usada na reinicialização chamando setPersistent().
A classe auxiliar PhpConfig
facilita a invocação de um subprocesso PHP (com ou sem o Xdebug carregado), independentemente de ter havido uma reinicialização.
Cada um de seus métodos retorna um array de opções PHP (para adicionar à linha de comando) e configura o ambiente para a estratégia necessária. O método getRestartSettings() é usado internamente.
useOriginal()
- Xdebug será carregado no novo processo.useStandard()
- Xdebug não será carregado no novo processo - veja configurações padrão.userPersistent()
- Xdebug não será carregado no novo processo - veja configurações persistentesSe não houve reinicialização, um array de opções vazio será retornado e o ambiente não será alterado.
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 = ''
As seguintes configurações de ambiente podem ser usadas para solucionar problemas de comportamento inesperado:
XDEBUG_HANDLER_DEBUG=1
Envia mensagens de status para STDERR
, se estiver definido, independentemente de qualquer registrador PSR3. Cada mensagem tem o prefixo xdebug-handler[pid]
, onde pid é o identificador do processo.
XDEBUG_HANDLER_DEBUG=2
Como acima, mas adicionalmente salva o arquivo ini temporário e informa sua localização em uma mensagem de status.
A API é definida por classes e seus elementos acessíveis que não são anotados como @internal. A classe principal possui dois métodos protegidos que podem ser substituídos para fornecer funcionalidades adicionais:
Por padrão, o processo será reiniciado se o Xdebug estiver carregado e não estiver em execução com xdebug.mode=off
. Estender este método permite que um aplicativo decida, retornando um valor booleano (ou equivalente). Ela só é chamada se MYAPP_ALLOW_XDEBUG
estiver vazia, portanto não será chamada no processo reiniciado (onde esta variável contém dados internos), ou se a reinicialização tiver sido substituída.
Observe que os setters setMainScript() e setPersistent() podem ser usados aqui, se necessário.
Um aplicativo pode estender isso para modificar o arquivo ini temporário, cuja localização é fornecida na propriedade tmpIni
. Novas configurações podem ser anexadas com segurança ao final dos dados, que são finalizados com PHP_EOL
.
O parâmetro $command
é uma matriz de argumentos de linha de comando sem escape que serão usados para o novo processo.
Lembre-se de terminar com parent::restart($command)
.
Este exemplo demonstra duas maneiras de estender a funcionalidade básica:
Para evitar a sobrecarga de iniciar um novo processo, a reinicialização será ignorada se um comando de ajuda simples for solicitado.
O aplicativo precisa de acesso de gravação aos arquivos phar, portanto, forçará uma reinicialização se phar.readonly
estiver definido (independentemente de o Xdebug estar carregado) e alterará esse valor no arquivo ini temporário.
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 );
}
}
O diretório testsApp
contém scripts de linha de comando que demonstram o funcionamento interno em vários cenários. Consulte Scripts de Teste Funcional.
compositor/xdebug-handler está licenciado sob a licença MIT, consulte o arquivo LICENSE para obter detalhes.