- Отладка PHP-кода с помощью Xdebug в PHPStorm
- Настройка отладки PHP в OpenServer
- Настройка отладки в PHPStorm
- Настройка отладки в браузере Google Chrome
- Начинаем отлаживать
- Debugging in PHP
- Table of Contents
- User Contributed Notes 12 notes
- How to set up VSCode, PHP Debug and XDebug (Windows 10)
- 2 Answers 2
- Long story (how to check that VSCode is listening on port 9000)
- Short Story
- Afterthought
Отладка PHP-кода с помощью Xdebug в PHPStorm
Отладка программы – это процесс, в ходе которого обнаруживают и устраняют баги. Для этого нам нужно знать, например, значения переменных на каждом шаге выполнения программы, или смотреть выполнилось ли условие, или даже погружаться в работу рекурсивных функций.
Собственно, так как многим рекурсия показалась сложной, то я решил сделать урок по отладке кода на PHP. В этой статье мы рассмотрим настройку отладки с помощью PHP-расширения Xdebug, а производить отладку мы будем в уже известной нам IDE PHPStorm.
Настройка отладки PHP в OpenServer
Первым делом давайте включим расширение Xdebug в файле конфигурации PHP (php.ini). Для этого идём в меню OpenServer -> Дополнительно -> Конфигурация -> PHP.
Здесь нам нужно найти секцию [Xdebug]. Как правило, она находится в конце этого файла.
Здесь нам нужно раскомментировать (или просто добавить) строки:
Должно получиться так:
После чего нужно сохранить файл (CTRL + S) и перезапустить веб-сервер.
На этом настройка веб-сервера для отладки завершена.
Настройка отладки в PHPStorm
Теперь нам нужно настроить отладку в PHPStorm. Первым делом идём в настройки:
File -> Settings
Здесь в левом меню выбираем:
Languages & Frameworks -> PHP -> Debug
Прокручиваем правую часть до секции Xdebug, и задаём следующие настройки:
- Debug port: 9000
- Force break at first line when no path mapping specified: выключено
- Force break at first line when a script is outside the project: выключено
Сохраняем изменения, нажав на “OK”.
Теперь в верхней правой части программы жмём на такую выпадающую менюшку:
И жмём “Edit Configuration”.
В появившемся окне в левом верхнем углу жмём на плюсик и выбираем “PHP Remote Debug”.
И нажимаем справа от пункта “Servers” на три точки:
В появившемся окне снова жмём на плюсик, и у нас в списке появляется новый сервер. Давайте зададим для него следующие настройки:
- Name: localhost
- Host: localhost
- Port: 80
- Debugger: Xdebug
Сохраняем нажатием на “OK” и завершаем заполнять ранее открытую настройку. А именно:
- Ide key (session id): PHPSTORM
И убеждаемся, что в “Servers” указан только что созданный нами “localhost”.
Сохраняем, нажав “OK”. На этом конфигурация PHPStorm для отладки PHP-приложений с помощью Xdebug завершена.
Настройка отладки в браузере Google Chrome
Дело осталось за малым – нужно только установить расширение для Chrome под названием Xdebug helper.
Заходим в Chrome и переходим по адресу: Xdebug helper
Напротив расширения Xdebug helper жмём кнопку “Установить”.
После того, как расширение установлено в верхнем правом углу Chrome появится значок жучка. Жмём по нему правой кнопкой мыши и нажимаем “Параметры”.
Здесь в пункте IDE key в выпадающем меню выбираем PhpStorm.
И нажимаем “Save”.
На этом предварительная настройка завершена.
Начинаем отлаживать
Итак, все настройки выполнены и дело осталось за малым – начать пользоваться отладчиком.
Давайте в нашем index.php запишем следующий код:
А затем слева от строки $x *= 2; кликнем по пространству между номером строки и самим кодом – появится красная точка.
Это брэйкпоинт (breakpoint), или, как её ещё называют – точка останова. К ней мы вернёмся чуть позже.
Теперь давайте включим отладчик – в правом верхнем углу PHPStorm, там где раньше была пустая выпадашка, а теперь выбран пункт “XDebug”, жмём на значок жучка.
Отладка на уровне PHPStorm запущена.
Теперь возвращаемся в Chrome, заходим на адрес нашего проекта (в моём случае http://myproject.loc/) и после того как зашли(. ) жмём на значок жучка (уже в Chrome) и выбираем пункт “Debug”.
После чего значок станет зелёным.
Теперь можно в Chrome обновить страницу, и увидеть, что она повисла в режиме загрузки.
А в окне PHPStorm увидеть следующее:
Наша программа остановила своё выполнение в месте брэйкпоинта.
Внизу программы (во вкладке Variables) мы можем видеть значения всех переменных в данный момент. Как видим, сейчас (до выполнения строки 5) $x равна 7.
Давайте нажмём кнопку “F8”. Она осуществляет выполнение кода на текущей строке и останавливается перед следующим действием.
Умножили $x на 2, и как видим, её значение стало равно 14. Вот так с помощью отладки мы можем отслеживать значения переменных в какой-то определенный момент работы программы.
Помимо этого, есть, разумеется, и другие сочетания клавиш, которые используются во время отладки.
Давайте прямо сейчас нажмём F9. Это приведет к тому, что программа продолжит выполнение до следующего брэйкпоинта (да, их можно наставить сколько угодно). Если их больше не встретится (как в нашем примере), то программа просто завершит свою работу.
Давайте поиграемся с кодом посложнее:
И установим два брэйкпоинта на строках 5 и 10.
После чего обновим нашу страничку в браузере и попадём в первый брэйкпоинт на строке 10:
Здесь мы видим значения переменных $x и $y внутри функции. Нажмём F9 и программа выполнится до того момента, пока не дойдёт до следующего брэйкпоинта.
Здесь мы уже видим, что внутри функции доступны переменные $x и $y. Но это уже другие переменные, не те, что были переданы в функцию getSumOfCos(). Вот мы и увидели локальную область видимости в действии.
Помимо этого, в левом нижнем углу есть окошечко “Frames”, это так назваемый “стек вызовов”. Здесь мы можем переключаться на места, откуда был вызван наш код ранее. Так мы можем переключиться в то место, где была вызвана функция getSum().
И можем посмотреть переменные, которые были доступны в той области видимости (уровнем выше).
Ещё в правом нижнем углу можно увидеть окошечко “Watches”. Это такое место, где можно задать переменные или даже выражения, значения для которых вы хотели бы видеть всегда под рукой. Добавляются они туда с помощью плюсика. В появившемся окошечке вводим выражение, которое мы бы хотели отслеживать. Пусть это будет $x/2.
Отлично, осталось рассмотреть ещё одну клавишу и вы готовы к бою – F7. Она позволяет зайти “внутрь” какой-либо конструкции.
Давайте закончим отладку нажатием F9. Поставим теперь только один брэйкпоинт на строке номер 15 и обновим страничку в браузере.
Если сейчас нажать F8, то программа закончит своё выполнение, и мы не попадём внутрь функций. Так происходит потому что во время отладки мы работаем на определённых уровнях вложенности, и если нам нужно будет попасть внутрь функции, то нужно будет нажать F7, находясь на строке 15. После этого мы окажемся на строке 10. Если сейчас нажать F8, попадём на строку 11. Ещё раз – на строку 12. Если мы сейчас, находясь на 12 строке нажмем F7, то попадём внутрь функции getSum() на строку 5. А если бы мы нажали F8, то мы просто поднялись бы на уровень выше, в то место, где была вызвана функция getSumOfCos().
В принципе, большего для отладки вам не потребуется (лично мне этого хватает).
Ну а сейчас пришла пора поотлаживать рекурсивные функции. Коль уж у вас возникли проблемы с прошлой домашкой – давайте их решать =)
Давайте возьмем и поковыряем код из предыдущей домашки:
Поставим брэйкпоинт на 3 строке и запустим программу.
Итак, в функцию попала переменная $x = 3. Нажимаем F8, и попадаем на строку 7, так как условие не выполнилось. Теперь нажмём F7 и снова попадём в начало нашей функции, но теперь $x = 2. И при этом стек вызовов увеличился ещё на одну строку, то есть мы вошли в ещё один уровень вложенности.
Жмём F8 и снова оказываемся на строке 7. Нажимаем F7 и снова попадаем в новый вызов функции, только уже $x = 1, а в стэке вызовов появился ещё один уровень.
Снова F8 и затем F7. И вот уже в функции $x = 0.
Жмём F8 и оказываемся на строке 4 (теперь условие выполнилось). На этой строке программа выведет 0.
Жмём F8 и попадаем на строку 5. Сейчас функция завершит свою работу и мы попадём на уровень выше, в то место, где она была вызвана. Итак, жмём F8.
Вуаля, мы вернулись на уровень выше, там, где переменная $x = 1.
И попали мы на следующую строку, после той в которой вызвали функцию numbers(1 — 1). И на этой строке мы вывели уже число 1. А дальше – жмите F8 и наблюдайте за ходом выполнения программы. Надеюсь теперь рекурсия для вас понятна =)
Debugging in PHP
Table of Contents
User Contributed Notes 12 notes
I find it very useful to print out to the browsers console instead of just var_dumping:
function console_log( $data ) <
echo »;
>
Usage:
$myvar = array(1,2,3);
console_log( $myvar ); // [1,2,3]
A good example of data output to the console via » );
> else <
echo ( «» );
>
>
>
/**
* 浏览器友好的变量输出,便于调试时候使用
*
* @param mixed $var 要输出查看的内容
* @param bool $echo 是否直接输出
* @param string $label 加上说明标签,如果有,这显示»标签名:»这种形式
* @param bool $strict 是否严格过滤
* @return string
*/
if (! function_exists ( ‘dump’ )) <
function dump ( $var , $echo = true , $label = null , $strict = true ) <
$label = ( $label === null ) ? » : rtrim ( $label ) . ‘ ‘ ;
if (! $strict ) <
if ( ini_get ( ‘html_errors’ )) <
$output = print_r ( $var , true );
$output = «» ;
> else <
$output = $label . » : » . print_r ( $var , true );
>
> else <
ob_start ();
var_dump ( $var );
$output = ob_get_clean ();
if (! extension_loaded ( ‘xdebug’ )) <
$output = preg_replace ( «/\]\=\>\n(\s+)/m» , «] => » , $output );
$output = » ;
>
>
if ( $echo ) <
echo ( $output );
return null ;
> else <
return $output ;
>
Following example above using variable-lenght arguments to support similar Web API’s console.log implementation
function console_log ( . $messages ) <
$msgs = » ;
foreach ( $messages as $msg ) <
$msgs .= json_encode ( $msg );
>
How to set up VSCode, PHP Debug and XDebug (Windows 10)
I want to use VSCode’s ‘PHP Debug’ plugin with Xdebug to debug PHP scripts.
But when I choose «Debug|Start Debugging F5» the little debug pop-up appears and I am stuck. Buttons for Pause, Restart, Stop are active. Buttons for Step over, into, out are inactive (greyed out). Nothing happens in the debug console.
(1) VSCode 1.42.1 is installed
(2) XAMPP v3.2.4 is up and running
(3) Xdebug is installed using the wizzard and pasting my phpinfo() data to determine the correct version. When I start ‘admin’ from XAMPP Control Panel and review phpinfo, the browser shows me (amongst many other things):
(please note that «Program Files_» is NOT the protected «Program Files» directory, XAMPP has write access as shown for point (9) below)
(5) the Windows path has C:\Program Files_\xampp\php; in it
(6) when I use Code Runner extension in VSCode to run a «Hello World.php» script is runs just fine
(7) launch.json for the VSCode debugger has
(8) my Windows firewall has an inbound rule to allow TCP traffic on port 9000.
(9) when I just run the code, xdebug.log (see php.ini ) is updated with
But when I use «Debug|Start Debugging F5» nothing happens in xdebug.log.
That is all the information that I thought relevant so far. Which leaves me like so:
Do you wizards out there have any idea where to dig? Which config file to tweak? Which log file to consult?
footnote: debugging of Python scripts in VSCode works just as expected.
2 Answers 2
@LazyOne’s comment provided the clue and the tools to stumble upon the solution .
And the answer turns out to be quite embarrassing.
Long story (how to check that VSCode is listening on port 9000)
- start XAMPP, start VSCode
- open your php script
- set a breakpoint
- open a Linux shell (I used Bash on Ubuntu on Windows)
- run telnet 0.0.0.0 9000 or telnet localhost 9000 in the shell and observe the connection fail
- start debugging and see the frozen debug pop-up as described above
- run telnet 0.0.0.0 9000 or telnet localhost 9000 in the shell and note the difference: you are connected to VScode!
- click the stop button on the frozen debug pop-up and observe in the shell
Conclude that VSCode is indeed listening to both 0.0.0.0:9000 and localhost:9000.
- scratch your head and go back to VSCode
- start debugging
- notice the orange status bar at the bottom that says «Listen to XDebug»
- notice the drop down menu just below the menu bar that says «green arrow» and «Listen for XDebug»
- explore the drop down and (re)discover the second configuration «Launch currently open script», realize/remember that your launch.json had 2 configurations
- click the green arrow when «Launch currently open script» is selected, see a error pop up along the lines «listen EARDRINUSE: address already in use . 9000»
- cancel the error message, stop debugging by clicking on the stop button of debug pop-up, notice that menu bar at the bottom turns blue
- click the green arrow when «Launch currently open script» shows in the drop-down again . and notice that debugging starts as expected
- rejoice! praise @LazyOne for their help! thank the heavens for the stackoverflow community!
- the «Listen for XDebug» configuration in launch.json is used to debug a script that was started from a browser session: (i) set your breakpoints in VSCode, (ii) start debugging with «Listen for XDebug» configuration, (iii) start the scripts by initiating a request i the browser, (iv) observe VSCode if a breakpoint is triggered while the request is processed
Short Story
Make sure that «Launch currently open script» is selected as configuration when you start debugging your php script in VSCode, see screenshot below.
Afterthought
I have changed my launch.json to
This way the «Launch currently open script» is the default and will be used when I start debugging with «Debug|Start Debugging F5» from the main menu.