Исправление ошибок в PHP-приложениях при помощи Zend DebuggerИсточник: wwwibmcom
Специализированное приложение, называемое отладчиком, тестирует выполняющийся код, позволяя остановить выполнение в произвольный момент времени, исследовать объекты, стек вызовов и даже изменить значение переменной "на лету". Узнайте, как использовать отладчик для исправления ошибок в вашем PHP-коде. Согласно популярному поверью, первым компьютерным "жучком" действительно было насекомое - злополучная ночная бабочка, севшая на реле компьютера Mark II Aiken Relay Calculator, тестировавшегося в Гарвардском Университете. Оператор записал в журнале 9 сентября 1947 года "First actual case of [a] bug being found [in a computer]" (Первый реальный случай обнаружения насекомого [в компьютере]). Эта запись и печально известное насекомое изображены на рисунке 1. Рисунок 1. Печально известное насекомое, попавшее в Mark II
На самом деле этимология (или энтомология ?) термина "жучок" (bug) намного прозаичнее и, по-видимому, старше заблудившейся бабочки лет на 70. В 1848 году Томас Эдисон, описывая механические неисправности, писал: "Сначала работает интуиция и приходит озарение, но затем возникают трудности - вещь перестает работать, и тогда проявляют себя "жучки" - маленькие поломки и проблемы…" Очевидно, что этот термин уже был жаргонным во времена Эдисона. Если вы являетесь разработчиком программного обеспечения, то, возможно, несколько успокоитесь и воодушевитесь, узнав, что даже Эдисону приходилось "отлаживать" свои изобретения (Эдисон никогда не использовал термин "отладка"; этот термин попал в язык сравнительно недавно из профессионального жаргона авиамехаников времен Второй мировой войны). Возможно, вам хотелось бы, чтобы многообразие жучков было ограничено их шестиногой разновидностью, и все, что вам нужно было бы для написания совершенного кода, - это USB-мухобойка или электронный эквивалент ловушки для тараканов (Roach Motel). "Компьютерные жучки входят, но не выходят " (может ли кто-либо добавить эту функциональность в следующую версию Subversion?). Напрасные мечтания. Увы, как отмечал Эдисон, жучки являются неотъемлемой частью любого инженерного предприятия. Опять же по поводу изобретательства Эдисон писал: "Необходимы месяцы интенсивных наблюдений, изучения и труда, чтобы достичь результата - коммерческого успеха или провала". К счастью, разработчики программного обеспечения имеют инструментальные средства, облегчающие "наблюдения" и сокращающие месяцы до минут или, в худшем случае, до часов или суток. В предшествующей статье ("Исправление ошибок в PHP-приложениях при помощи Xdebug" ) были рассмотрены разнообразные методики сбора улик для "вскрытия" причины сбоя. Однако такой "посмертный" анализ часто труден и продолжителен, поскольку требует выдвижения и проверки гипотез. При отсутствии необходимой информации нужно переделывать исходный код, повторять действия и начинать расследование заново - этот процесс потенциально требует многочисленных итераций. В данной статье исследуется намного более эффективная и рациональная методика - интерактивная отладка . Специализированное приложение, называемое отладчиком , помогает тестировать выполняющийся код, позволяя останавливать его выполнение в произвольных точках прерывания, исследовать объекты, стек вызовов и рабочую среду и даже изменять значение переменных "на лету". В демонстрационных целях мы будем использовать Zend Debugger - расширение системы Zend, тестирующее выполняющееся PHP-приложение. Загрузить и использовать Zend Debugger можно бесплатно. Однако для управления Zend Debugger и просмотра диагностической информации необходимо объединить его с клиентским приложением. Клиентское приложение может быть как элементарным, выполняющимся из командной строки, так и полнофункциональной интегрированной средой разработки (IDE), обладающей функциями редактора, завершения кода, визуальных браузеров классов и т.д. С Zend Debugger могут взаимодействовать несколько клиентских приложений с открытыми исходными кодами, включая PHP-плагин для Eclipse. Однако я в качестве IDE для PHP предпочитаю использовать Zend Studio, предлагаемую компанией Zend Technologies, разрабатывающей как систему с открытыми исходными кодами, так и коммерческую PHP-систему времени исполнения. В отличие от самого PHP, Zend Studio является коммерческим продуктом. Продукт можно загрузить и использовать бесплатно на протяжении 30 суток (чего вполне достаточно для того, чтобы опробовать многочисленные возможности IDE), но затем необходимо купить лицензию, если вы захотите продолжать ее использование. По моему мнению, эта лицензия оправдывает каждый заплаченный пенни. Попробуйте разные клиентские приложения и найдите то, которое вам подходит. Например, многие IDE объединяются с популярными редакторами, поэтому нет необходимости заново изучать массу клавиатурных сокращений. Независимо от вашего выбора после работы с отладчиком вы наверняка удивитесь, как раньше жили без него. Скажите "Прощай, Установка Zend Studio и Zend DebuggerДля начала загрузите программное обеспечение Zend Studio и Zend Debugger. Приведенные здесь инструкции относятся к Mac OS X, но для операционных систем Linux® и Microsoft® Windows® они аналогичны (на Web-странице Zend Studio приведены конкретные инструкции для каждой из этих платформ). В действительности можно также установить и запустить Zend Studio на локальной системе, а отладчик развернуть на сервере для удаленной отладки. Независимо от вашей платформы убедитесь в том, что на вашей системе установлена рабочая версия PHP V4 или PHP V5 - программное обеспечение Zend работает с любой версией PHP. Поскольку Mac OS X в настоящее время поставляется с PHP V4 (V4.4.7, если быть более точным), в данной статье используется эта более старая версия PHP. Для установки инструментальных средств Zend:
Для проверки функционирования PHP и Web-сервера перейдите в каталог ~/Sites/ и создайте файл info.php со следующим содержимым: <?php phpinfo(); ?>
Укажите в адресной строке вашего браузера http://localhost/~username/info.php, где username - это имя вашей учетной записи в Mac OS X. Если настройка выполнена правильно, вы должны увидеть раздел Рисунок 4. Проверка функционирования отладчика
Запомните настройку Между прочим, если этот процесс установки представляется сложным или нужно сэкономить время, можно загрузить Zend Core или Zend Platform. Оба этих продукта являются коммерческими, но каждый из них предварительно настроен на использование Zend Debugger. Приведенные в оставшейся части данной статьи инструкции так же хорошо работают и с Zend Core или Zend Platform. Подключение к Zend DebuggerКомбинация Zend Studio и Zend Debugger позволяет удаленно управлять системой Zend. Zend Studio выступает в роли панели управления, отображающей информацию о внутренних деталях системы. Среди прочих данных можно просматривать выполняющийся исходный код, состояние переменных и состояние рабочей Web-среды. Zend Debugger является своего рода посредником - он передает информацию из системы Zend в Zend Studio и команды из Zend Studio в систему Zend. В число его команд входят функции отладки, например, Таким образом, для отладки PHP-приложения мы настраиваем Zend Studio на подключение к отладчику и затем открываем приложение в браузере, как обычно. Когда приложение начинает выполняться, отладчик вмешивается в его работу и передает управление в Zend Studio. А там мы принимаем управление на себя. Настройка Zend StudioНиже приведен простой способ установки соединения с Zend Debugger (позднее я приведу более сложный сценарий и рассмотрю дополнительные приемы отладки):
Теперь все готово для написания и отладки PHP-кода. Отладка примера исходного кодаZend Studio содержит все необходимое для написания PHP-кода: редактор для изменения отдельных файлов, менеджер файлов, чтобы собирать файлы в проект, браузер PHP-классов и модулей, используемый в качестве справки, окно вывода для просмотра промежуточных результатов работы и браузер рабочей среды, отображающий переменные, стек вызовов и выходной буфер. Но еще лучше то, что редактор является контекстно-чувствительным и может автоматически завершать управляющие PHP-структуры, ключевые слова и разделители строк. Для начала щелкните кнопкой мыши в окне Editor, расположенном в верхней центральной части Zend Studio. Введите фрагмент исходного кода листинга 1 (чтобы опробовать функциональные возможности завершения кода), предназначенного для вывода чисел 1-10. Листинг 1. Вывод чисел 1-10<?php $counter = 1; while ( $counter < 10; ) { printf( "%d\n", $counter ); increment( $counter ); } function increment( $i ) { $i++; return; } ?>
После завершения ввода кода для его выполнения нажмите зеленую кнопку Play в инструментальной панели. Вместо вывода 1-10 код распечатывает бесконечный список цифр 1. Нажмите красную кнопку Stop для прекращения работы программы. Очевидно, что здесь есть ошибка (жучок). Первый вопрос: что происходит с Рисунок 6. Установка точек прерывания в примере кода
Затем нажмите кнопку Play для перезапуска приложения. Выполнение начинается и сразу останавливается на строке 7. В панели Debug Output (справа) содержится некоторая выходная информация, а на вкладке Variables окна Debug показан список переменных. Массивы отмечаются квадратными скобками ( Теперь нажмите синюю стрелку вниз на инструментальной панели для выполнения одного оператора в функции (сравните ее действие с синей правой стрелкой и черточкой, которая вызывает функцию и останавливает выполнение на следующем после вызова функции операторе). Теперь курсор должен находиться в строке 11, а на вкладке Variables должна отображаться только одна переменная: формальный аргумент Снова нажмите стрелку вниз для прохода строки 11. Рисунок 7. Стек обратной трассировки
Снова нажмите стрелку вниз для возврата в строку 5. Удивительно, но значение Нажмите кнопку Stop, а затем опять кнопку Play. Пошагово выполните программу и увидите 1, 2, 3, . . . 8, 9. Что произошло с 10? Ответ очевиден: это ошибка диапазона ("off-by-one error"). Просто измените Хотя пример немного надуманный, тем не менее он демонстрирует несколько фундаментальных приемов интерактивной отладки:
Для более полного изучения Zend Studio используйте IDE (по крайней мере, временно) при написании PHP-кода и пройдитесь по всем вкладкам. Вы обнаружите множество функциональных возможностей. Даже если вы будете редактировать код в другой программе, все равно можно использовать Zend Studio для отладки классов, методов и модульных тестов. Написание последних в IDE особенно полезно. Отладка вашего PHP-приложенияКонечно, настоящая ценность PHP-отладчика проявляется при работе с Web-приложением в режиме реального времени. Вот пример такого сценария. Приготовление приложения pizzaВ листингах 2 и 3 приведено простое PHP-приложение с классом, методами и некоторым кодом-оболочкой (wrapper). Приложение index.php, показанное в листинге 2 , создает заказы на пиццу, используя класс Листинг 2. Приложение index.php для заказа пиццы<?php include_once( 'pizza.class.php' ); $large = new Pizza( 'L', null ); echo $large->price() . '<br />'; $toppings = array(); $toppings[] = 'pepperoni'; $toppings[] = 'sausage'; $xl = new Pizza( 'XL', $toppings ); echo $xl->price() . '<br />'; $special = new Pizza( 'XL' ); $special->add( null ); $special->add( 'pepperoni' ); $special->add( 'pepperoni' ); $special->add( 'anchovies' ); $special->add( 'anchovies' ); $special->add( 'olives' ); echo $special->price() . '<br />'; ?>
Листинг 3. Очень вкусный класс Pizza<?php class Pizza { var $size; var $toppings = array(); var $price; function Pizza( $size = "R", $toppings = null ) { $this->size = $size; $this->toppings = $toppings; } function size() { return( $this->size ); } function price() { $this->price = 10; $multiplier = 1; switch ( $this->size ) { case 'L': $multiplier = 1.25; break; case 'XL': $multiplier = 2; break; } $this->price = $this->price + ( sizeof( $this->toppings() ) ) * $multipler; return( $this->price ); } function toppings() { return( $this->toppings ); } function add( $topping ) { $this->toppings[] = $topping; } } ?>
Для создания проекта:
Что с моим исходным кодом?Все готово для отладки приложения. Нажмите кнопку Play: приложение запускается и выводимая им информация отображается в панели Debug Output. Она выглядит примерно так: Content-type: text/html 10<br />10<br />10<br />
Почему все три пиццы по $10? Если вы посмотрите на панель Debug Messages, ответ очевиден: переменная Эту ошибку можно обнаружить также другим способом, когда она не так очевидна (как это обычно и бывает). Выполните двойной щелчок левой кнопкой мыши на файле Pizza.class.php проекта, поместите курсор в строку 29 и выберите Debug > Add/Remove Breakpoint. Строка становится розовой. Выполните двойной щелчок левой кнопкой мыши на index.php и нажмите кнопку Play. Выполнение прерывается на строке 29. Если посмотреть на окно Debug, значение В качестве упражнения выполните с помощью IDE пошаговый проход через другую ошибку - логическую ошибку, которая может вызвать завышение цены. Очистите все точки прерывания, затем в index.php установите точку прерывания в строке 14. Установите также точки прерывания на функциях Рисунок 13. Неправильная пицца
Чтобы исправить ошибку, запретите значение null в качестве допустимой начинки (на самом деле ошибка заключается в index.php, но вы можете добавить "защиту от дурака" в функцию function toppings() { if ( is_array( $this->toppings ) ) { return( array_unique( $this->toppings ) ); } return( 0 ); } function add( $topping ) { if ( ! is_null( $topping ) ) { $this->toppings[] = $topping; } }
Подключение к браузеруВ качестве последнего упражнения загрузите приложение в браузер и выполните его отладку в IDE. Это типичный сценарий: просмотр вывода в браузере, взаимодействие с Web-страницами, пошаговое выполнение приложения для проверки его реакции:
Если бы приложение имело формы, можно было бы установить точку прерывания в обработчике формы и просмотреть входные параметры. В окне Debug доступны все глобальные переменные рабочей среды, глобальные переменные PHP и параметры каждого запроса Web-сервера. По окну Debug URL определите момент, когда приложение остановится в отладчике. Обычно Web-приложение на PHP содержится в одном каталоге, а главная страница называется index.php. Ссылки на этой "домашней" странице указывают на другие PHP-страницы, которые инкапсулируют функциональность. Например, URL .../store/index.php может представлять домашнюю страницу интерактивного магазина, а URL .../store/cart/index.php может реализовывать корзину покупок. Можно настроить Zend Studio на отладку одной, нескольких или всех PHP-страниц, расположенных в отдельном корневом каталоге приложения. Например, если в корзине покупок есть ошибки, можно загрузить сеанс отладки при открытии любой страницы в cart/. Можно также просто начать сеанс при загрузке основной страницы index.php и отладить приложение полностью. А лучше всего скомбинировать Zend Studio, Internet Explorer® или Mozilla Firefox и Zend Debugger Browser Toolbar для загрузки сеанса отладки непосредственно из браузера. Можно отлаживать текущую страницу, все страницы сайта или работу одной формы. Новый способ работыИнтерактивный отладчик похож на маленькую лампочку, включающуюся у вас над головой. Задачи, требующие трудоемкой диагностики на каждом шаге работы функции, неожиданно становятся простыми - установите точку прерывания, выполните столько кода, сколько понадобится, и наблюдайте, что происходит в это время в каждом операторе. Держите записную книжку наготове и отмечайте причины и следствия, данные наблюдений и гипотезы. Zend Studio - это не единственный возможный отладчик. Попробуйте другие и найдите тот, который наилучшим образом соответствует вашему стилю работы. Вы будете удивляться, как раньше обходились без отладчика. |