Php вывод отладочной информации

Отладка — Основы PHP

Один из наиболее достоверных способов убедиться, что человек разбирается в программировании — посмотреть, как он отлаживает программу, анализирует возникающие ошибки и устраняет их.

Навык отладки не появляется сам по себе, его необходимо развивать, и начинать это нужно как можно раньше. Этому способствует настройка локальной среды разработки и повторение всего, что делается в курсах у себя на компьютере. Следующие курсы как раз помогают проделать эти шаги.

Первое, что вам понадобится для отладки — хотя бы минимальное знание английского языка и умение пользоваться словарем.

В отличие от документации языка, которую можно найти на русском, сообщения об ошибках всегда отображаются на английском. Не пытайтесь отгадывать или менять код методом тыка, в надежде, что он заработает.

Прочитайте сообщение об ошибке, поймите его — это ключевое действие, на основе которого можно планировать дальнейшие шаги:

function App\Users\undef() /usr/src/app/src/Users.php:9 /usr/src/app/tests/UsersTest.php:27 

Вывод ошибок делится на две части: непосредственно сообщение с ошибкой и бэктрейс.

Бэктрейс (он же «стектрейс») — это список всех вызовов функций от запуска программы вплоть до того места, где произошла ошибка. Это очень важный инструмент, который позволяет увидеть, как выполнялась ваша программа и какие функции вызывались.

Отладка всегда сводится к двум вещам:

  • Перевести сообщение об ошибке
  • Найти в бэктрейсе место в своем коде, после которого произошла ошибка

Каждая строчка в бэктрейсе представляет собой указание на файл и строчку, в которой была вызвана соответствующая функция. Бэктрейс называется back, потому что вывод строк идет в обратном порядке: наверху находится последний вызов, внизу — первый.

В рамках одного бектрейса возможны ситуации, когда часть функций вызывается где-то в сторонних библиотеках, а часть — в вашем коде.

Типы ошибок

Наиболее простые и понятные ошибки — синтаксические. Они связаны с тем, что код записан неверно: например, забыта точка с запятой в конце инструкции.

В выводе таких ошибок всегда присутствуют фразы parse error и syntax error.

Чтобы их исправить, нужно внимательно изучить то место в коде, на которое указывает ошибка:

'>' in /usr/src/app/src/Users.php on line 7 

Еще одна большая группа ошибок называется ошибками программирования. Например, к ним относятся:

  • Вызов несуществующей функции
  • Использование необъявленной переменной
  • Передача неверных аргументов в функции, например, аргументов, имеющих неверный тип

Эти ошибки исправить труднее, чем синтаксические. Обычно они возникают в результате неправильной логики в другом, более раннем вызове.

Последний тип ошибок — логические. Исправить такие ошибки бывает крайне сложно, так как программа продолжает работать, но выдает неверный результат. Причем обычно программа выдает неверный результат не всегда, а только лишь для некоторых входных данных.

В подавляющем большинстве случаев проблема кроется в неверной логике, например, перепутана операция и вместо сложения выполняется вычитание:

 // Функция должна считать сумму чисел, но считает разность: function sum($a, $b)  return $a - $b; > 

Отладка

Существует множество способов отладить программу, но какой бы способ вы ни выбрали, общая идея отладки сводится к анализу того, как меняются значения переменных в процессе работы кода.

Рассмотрим конкретный пример. Ниже описана функция, которая считает сумму чисел от числа $start до числа $finish . Если начало равно трем, а конец — пяти, то программа должна вычислить: 3 + 4 + 5 :

 function sumOfSeries($start, $finish)  $sum = 0; for ($i = $start; $i  $finish; $i++)  $sum += $i; > return $sum; > 

В этом коде допущена ошибка. Вы ее видите? Если очень постараться, ее можно заметить, но на это никогда не надо надеяться.

Новички часто думают, что они невнимательны и очень расстраиваются, когда допускают такие ошибки. Хотим вас успокоить: опытные разработчики допускают такие ошибки не реже новичков.

Не так важно, что вы их допускаете. Главное — чтобы вы умели отладить этот код. Этим отличаются опытные разработчики от начинающих. Никогда не пытайтесь найти ошибку с помощью медитации над кодом, сверля его взглядом. Если быстрая проверка не дала ответа, то приступайте к отладке.

Некоторые начинающие разработчики думают, что опытные программисты могут просто взглянуть на код и понять, в чем ошибка. Это совсем не так. Просто глядя на такой код, невозможно понять, а что, собственно, пошло не так, уже не говоря о нахождении самой ошибки. Нам также нужно увидеть сообщение об ошибке и начать отладку.

Глядя на код функции sumOfSeries замечаем, что основных переменных там две: $i и $sum , именно они меняются в цикле. Из этого можно сделать ровно один вывод: нужно явно посмотреть, какие значения им даются на каждой итерации. После этого найти ошибку не составит труда.

Один из способов отслеживать значения переменных во время выполнения кода связан с использованием отладчиков. Отладчики интегрируются с популярными редакторами и позволяют визуально выполнить код по шагам, отслеживая любые изменения. Подробнее о том, как их использовать можно прочитать во множестве статей. Их можно найти по запросу: xdebug 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

Отладочная печать через print_r не очень удобна тем, что эта функция не ставит автоматически перенос строк. К тому же иногда хочется завершить выполнение кода сразу, как только был сделан первый вывод.

Для решения этой задачи на Хекслете подключена библиотека var-dumper. Она предоставляет две функции: dump и dd , которые доступны в любом месте программы. Первая просто красиво выводит переданный аргумент, а вторая — еще и останавливает выполнение кода:

Эта функция добавляет в вывод перевод строки, но особенно удобно использовать ее с массивами, которые мы скоро изучим.

Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Источник

Простой способ отладки программ на PHP

Я пользуюсь этим методом отладки программ на PHP уже лет, наверное, 10. И ещё ни разу он меня не подводил. Почему я решил поделиться этим способом с вами? Наверное потому, что больно смотреть на новичков, которые берут откуда-то код, или пишут приличную портянку сами, он (естественно) не работает и они начинают хаотично менять всё подряд, пытаясь каким-то способом «нащупать» то место, где таится ошибка. Но это на самом деле сложный путь, который не всегда приводит к результату. Итак, вот что я предлагаю.

Главное при отладке программ и поиске «багов» — это терпение и последовательность в действиях. Если вы не будете соблюдать пошаговый алгоритм, то ничего не получится, в итоге вы запутаетесь и ни к чему не придёте.

Сам пошаговый алгоритм сводится к последовательной расстановке меток в программе, обновлению страницы и наблюдению выводимой информации в браузере. Лучше всего начать всего с одной метки.

Каждая метка выглядит примерно так

echo 1; // Отладочная метка exit(); // Завершение работы скрипта

Интерпретатор кода PHP, дойдя до такой метки сделает следующее: выведя «1» в браузер, он немедленно прекратит выполнение кода программы. Таким образом, вы узнаете, что выполнение кода программы дошло до этого места, так как на экране будет выведена единичка и это будет последнее, что отобразится в браузере. Нет ничего проще, чтобы узнать — доходит ли до этой точки интерпретатор.

Вы можете не ставить exit(), если абсолютно уверены в том, что код не обновляет страницу после вывода (нет рефреша).

Дальнейшие действия могут быть следующими:

  • Можно переместить отладочную метку по коду ниже, чтобы выяснить — доходит ли интерпретатор до этой точки кода. Очень удобно, если вам надо выяснить факт срабатывания if() или факт входа в метод/функцию.
  • Можно выводить не «1», а что-то вроде «#1#» и потом искать его в исходном коде HTML браузера, чтобы не спутать отладочный вывод с обычным выводом (например, если страница содержит кучу других единичек).
  • Можно ставить сразу несколько меток в разных точках кода сразу, но эти метки непременно должны быть разные и желательно последовательные. Например, «#1#», «#2#», «#3#» и так далее. Так вы увидите в браузере все метки, до которых дошёл интерпретатор и сможете понять логику, которая в программе сработала.

Общее правило: продвигайтесь по коду очень медленно, стараясь не пропустить того момента, где таится баг. Старайтесь чаще использовать метод половинного деления.

Вывод значений переменных

Но что толку от того, что интерпретатор дошёл или не дошёл до какого-то места? Малоинформативно. Давайте добавим больше жизни!

Часто необходимо вывести значения конкретных переменных в конкретной точке кода. И тут нам пригодятся две мощнейшие функции — print_r() и var_dump(). Вот как их можно использовать.

Для того, чтобы увидеть содержимое переменной, используем print_r($var); или print_r($obj->var) если нужно посмотреть содержимое свойства конкретного объекта. Для того, чтобы увидеть значение true или false, используем var_dump(). Тут необходимо пояснить кое-что. Функция print_r() специально была придумана для того, чтобы красиво выводить значения разных типов. Причём она выводит и целые, и строки, и массивы и даже объекты. А вот true и false она не выводит, то есть вывод всегда будет равен пустой строке. Тут на помощь приходит var_dump(), который выводит точное значение и тип этого значения.

Использовать var_dump() везде я не рекомендую. Вывод, им генерируемый, выглядит намного запутаннее, чем вывод от print_r().

Итого, вот как будет выглядеть наша информативная метка:

echo '#4#'; print_r($var1); print_r($var2); echo '@4@';

Обычно я дублирую номер метки в обрамлении других символов, чтобы видеть, где закончился вывод тестируемых переменных. Это часто бывает полезно.

Можно ещё перед каждым print_r() выводить echo «var=»; чтобы понимать где и чьё значение отображается.

Замер времени выполнения части кода

Очень часто при профайлинге (а ещё чаще при поиске «тормозов» в коде) бывает необходимо замерить реальное время выполнения конкретного куска кода.

В PHP есть замечательная функция microtime(), которая возвращает текущее время в микросекундах. Если ей указать параметр true, то она будет возвращать его в виде числа с плавающей точкой, что нам и нужно.

Идея способа замера времени выполнения куска кода сводится к тому, чтобы запомнить текущее время перед началом этого куска и сравнить его с текущим временем в конце куска. То есть вот так:

$tt0 = microtime(true); // . код, который мы проверяем . $tt1 = microtime(true); echo '#1#='.($tt1-$tt0);

При этом после метки мы увидим время, потраченное на выполнение кода в секундах. Часто вы будете видеть что-то типа такого: 1.233433E-05, это инженерная форма записи очень малых и очень больших чисел. Можно привести её в нормальный вид, добавив функцию sprintf():

Немного больше кода, но зато вы будете видеть нормальные числа вроде 0.000012, т.е. 12 микросекунд.

Вот и всё на сегодня, завтра я напишу специальную статью, в которой расскажу об ещё одном способе отладки с использованием выгрузки лога в файл (бывает полезно, если не хочется нарушать нормальную работу сайта, то есть вывод разных меток на страницу недопустим).

Спасибо за внимание, не забудьте подписаться, чтобы не пропустить очередную статью!

Ещё статьи в этом разделе:

Источник

Читайте также:  Html inline style justify
Оцените статью