Один из наиболее достоверных способов убедиться, что человек разбирается в программировании — посмотреть, как он отлаживает программу, анализирует возникающие ошибки и устраняет их.
Навык отладки не появляется сам по себе, его необходимо развивать, и начинать это нужно как можно раньше. Этому способствует настройка локальной среды разработки и повторение всего, что делается в курсах у себя на компьютере. Следующие курсы как раз помогают проделать эти шаги.
Первое, что вам понадобится для отладки — хотя бы минимальное знание английского языка и умение пользоваться словарем.
В отличие от документации языка, которую можно найти на русском, сообщения об ошибках всегда отображаются на английском. Не пытайтесь отгадывать или менять код методом тыка, в надежде, что он заработает.
Прочитайте сообщение об ошибке, поймите его — это ключевое действие, на основе которого можно планировать дальнейшие шаги:
Error: Call to undefined function App\Users\undef()
/usr/src/app/src/Users.php:9
/usr/src/app/tests/UsersTest.php:27
Вывод ошибок делится на две части: непосредственно сообщение с ошибкой и бэктрейс.
Бэктрейс (он же «стектрейс») — это список всех вызовов функций от запуска программы вплоть до того места, где произошла ошибка. Это очень важный инструмент, который позволяет увидеть, как выполнялась ваша программа и какие функции вызывались.
Отладка всегда сводится к двум вещам:
- Перевести сообщение об ошибке
- Найти в бэктрейсе место в своем коде, после которого произошла ошибка
Каждая строчка в бэктрейсе представляет собой указание на файл и строчку, в которой была вызвана соответствующая функция. Бэктрейс называется back, потому что вывод строк идет в обратном порядке: наверху находится последний вызов, внизу — первый.
В рамках одного бектрейса возможны ситуации, когда часть функций вызывается где-то в сторонних библиотеках, а часть — в вашем коде.
Типы ошибок
Наиболее простые и понятные ошибки — синтаксические. Они связаны с тем, что код записан неверно: например, забыта точка с запятой в конце инструкции.
В выводе таких ошибок всегда присутствуют фразы parse error и syntax error.
Чтобы их исправить, нужно внимательно изучить то место в коде, на которое указывает ошибка:
PHP Parse error: syntax error, unexpected '}' in /usr/src/app/src/Users.php on line 7
Еще одна большая группа ошибок называется ошибками программирования. Например, к ним относятся:
- Вызов несуществующей функции
- Использование необъявленной переменной
- Передача неверных аргументов в функции, например, аргументов, имеющих неверный тип
Эти ошибки исправить труднее, чем синтаксические. Обычно они возникают в результате неправильной логики в другом, более раннем вызове.
Последний тип ошибок — логические. Исправить такие ошибки бывает крайне сложно, так как программа продолжает работать, но выдает неверный результат. Причем обычно программа выдает неверный результат не всегда, а только лишь для некоторых входных данных.
В подавляющем большинстве случаев проблема кроется в неверной логике, например, перепутана операция и вместо сложения выполняется вычитание:
<?php
// Функция должна считать сумму чисел, но считает разность:
function sum($a, $b)
{
return $a - $b;
}
Отладка
Существует множество способов отладить программу, но какой бы способ вы ни выбрали, общая идея отладки сводится к анализу того, как меняются значения переменных в процессе работы кода.
Рассмотрим конкретный пример. Ниже описана функция, которая считает сумму чисел от числа $start
до числа $finish
. Если начало равно трем, а конец — пяти, то программа должна вычислить: 3 + 4 + 5
:
<?php
function sumOfSeries($start, $finish)
{
$sum = 0;
for ($i = $start; $i < $finish; $i++) {
$sum += $i;
}
return $sum;
}
В этом коде допущена ошибка. Вы ее видите? Если очень постараться, ее можно заметить, но на это никогда не надо надеяться.
Новички часто думают, что они невнимательны и очень расстраиваются, когда допускают такие ошибки. Хотим вас успокоить: опытные разработчики допускают такие ошибки не реже новичков.
Не так важно, что вы их допускаете. Главное — чтобы вы умели отладить этот код. Этим отличаются опытные разработчики от начинающих. Никогда не пытайтесь найти ошибку с помощью медитации над кодом, сверля его взглядом. Если быстрая проверка не дала ответа, то приступайте к отладке.
Некоторые начинающие разработчики думают, что опытные программисты могут просто взглянуть на код и понять, в чем ошибка. Это совсем не так. Просто глядя на такой код, невозможно понять, а что, собственно, пошло не так, уже не говоря о нахождении самой ошибки. Нам также нужно увидеть сообщение об ошибке и начать отладку.
Глядя на код функции sumOfSeries
замечаем, что основных переменных там две: $i
и $sum
, именно они меняются в цикле. Из этого можно сделать ровно один вывод: нужно явно посмотреть, какие значения им даются на каждой итерации. После этого найти ошибку не составит труда.
Один из способов отслеживать значения переменных во время выполнения кода связан с использованием отладчиков. Отладчики интегрируются с популярными редакторами и позволяют визуально выполнить код по шагам, отслеживая любые изменения. Подробнее о том, как их использовать можно прочитать во множестве статей. Их можно найти по запросу: xdebug php <название редактора>.
В среде Хекслета отладчика нет, поэтому здесь та же задача выполняется другим способом — с помощью отладочной печати.
Суть такая же, как и в визуальном отладчике, но для вывода значения переменных используется обычная печать на экран:
<?php
function sumOfSeries($start, $finish)
{
$sum = 0;
for ($i = $start; $i < $finish; $i++) {
print_r('new iteration !!!!');
print_r($i);
$sum += $i;
print_r($sum);
}
return $sum;
}
sumOfSeries(3, 5);
// new iteration !!!!
// 3
// 3
// new iteration !!!!
// 4
// 7
То, что печатается на экран, отображается во вкладке OUTPUT
, на которую автоматически переключается редактор во время проверки. Из этого вывода сразу можно понять, что количество итераций цикла на одну меньше, чем нужно. Почему-то не выполняется сложение для последнего числа, которое обозначено как $finish
. И действительно, если посмотреть на определение, то видно, что там используется $i < $finish
вместо $i <= $finish
.
Отладочная печать через print_r
не очень удобна тем, что эта функция не ставит автоматически перенос строк. К тому же иногда хочется завершить выполнение кода сразу, как только был сделан первый вывод.
Для решения этой задачи на Хекслете подключена библиотека var-dumper. Она предоставляет две функции: dump
и dd
, которые доступны в любом месте программы. Первая просто красиво выводит переданный аргумент, а вторая — еще и останавливает выполнение кода:
<?php
$var = 'hello, world!';
dump($var);
Эта функция добавляет в вывод перевод строки, но особенно удобно использовать ее с массивами, которые мы скоро изучим.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»