Перезапустите процесс 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
, чтобы отменить автоматический перезапуск и разрешить Xdebug.MYAPP_ORIGINAL_INIS
для получения местоположения INI-файла в перезапущенном процессе Временный INI-файл создается из загруженных (и отсканированных) INI-файлов, при этом все ссылки на расширение Xdebug закомментированы. Текущие настройки ini объединяются, поэтому включается большинство настроек ini, выполненных в командной строке или в приложении (см. Ограничения).
MYAPP_ALLOW_XDEBUG
содержит внутренние данные, которые нужно пометить и использовать при перезапуске.MYAPP_ALLOW_XDEBUG
не установлен.См. примеры для получения дополнительной информации.
Асинхронная обработка сигналов включается автоматически, если загружено расширение pcntl. SIGINT
устанавливается в SIG_IGN
в родительском процессе и восстанавливается до SIG_DFL
в перезапущенном процессе (если не был установлен другой обработчик).
Начиная с PHP 7.4 в Windows, обработка 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
Возвращает true, если Xdebug загружен и работает в активном режиме (если он поддерживает режимы). Возвращает false, если Xdebug не загружен или запущен с xdebug.mode=off
.
Эти методы реализуют гибкий интерфейс и должны вызываться перед основным методом 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, в этом случае произойдет еще один перезапуск).
Это стратегия по умолчанию, используемая при перезапуске.
Использует переменные среды для удаления 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
содержит сценарии командной строки, которые демонстрируют внутреннюю работу в различных сценариях. См. Сценарии функционального тестирования.
композитор/xdebug-handler лицензируется по лицензии MIT, подробности см. в файле LICENSE.