ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Логические ошибки. Вспомогательное средство отладки переменных

Отладка

Логические ошибки

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

Логические ошибки могут вызываться простыми опечатками, как в следующем примере:

for ($i = 0; $i <10; $i++);
{
echo ' Что-то происходит . . .<br>';
}

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

Может показаться, что строка ' Что-то происходит . . .<br>' должна выводиться в цикле for 10 раз. Наличие лишней точки с запятой в конце первой строки означает, что цикл не распространяется на последующие строки. Цикл for будет выполнен 10 раз безрезультатно, а затем один раз будет выполнен оператор echo.

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

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

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

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

Предположим, что коммерческий сайт содержит текстовое поле Order Quantity (размер заказа). Можно ли предположить, что пользователи будут вводить только положительные числа? Если посетитель введет "минус десять", будет ли программа увеличивать остаток кредитной карточки на сумму десятикратной стоимости данного товара?

Предположим, форма содержит поле ввода суммы в долларах. Допускается ли ввод суммы со знаком доллара, либо без него? Допускается ли разделение тысяч запятыми? Некоторые проверки можно выполнять на стороне клиента (например, с помощью JavaScript), чтобы несколько разгрузить сервер.

Если информация передается другой странице, возможна ли ситуация, когда переваваемая строка содержит недопустимые символы для URL-адреса, такие как пробелы?

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

Вспомогательное средство отладки переменных

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

dump_variables.php — этот код может быть включен в страницы для вывода содержимого переменных для целей отладки

<?
// Эти строки форматируют выводимую информацию в виде
// HTML-комментариев и последовательно вызывают функцию dump_array()

echo "\n<!-- НАЧАЛО ДАМПА ПЕРЕМЕННЫХ -->\n\n";

echo "<!-- НАЧАЛО ПЕРЕМЕННЫХ GET -->\n";
echo '<!-- '.dump_array($HTTP_GET_VARS)." -->\n";

echo "<!-- НАЧАЛО ПЕРЕМЕННЫХ POST -->\n";
echo '<!-- '.dump_array($HTTP_POST_VARS)." -->\n";

echo "<!-- НАЧАЛО ПЕРЕМЕННЫХ СЕАНСА -->\n";
echo '<!-- '.dump_array($HTTP_SESSION_VARS)." -->\n";

echo "<!-- НАЧАЛО ПЕРЕМЕННЫХ COOKIE-НАБОРА -->\n";
echo '<!-- '.dump_array($HTTP_COOKIE_VARS)." -->\n";

echo "\n<!-- КОНЕЦ ДАМПА ПЕРЕМЕННЫХ -->\n";

// Функция dump_array() использует встроенную функцию print_r()
// и отменяет все завершающие HTML-дескрипторы комментариев

function dump_array($array)
{
$output = print_r($array, true);
$output = str_replace('-->', '-- >', $output);
return $output;
}
?>

Показанный в листинге код выводит четыре массива переменных, принимаемых страницей. Если страница вызывается с GET-переменными, POST-переменными, cookie-наборами либо переменными сеанса, все они будут выведены.

Выводимые значения заключены в HTML-дескрипторы комментариев, чтобы они были доступными для просмотра, но не конфликтовали с методами обработки браузером видимых элементов страницы. Сокрытие отладочной информации в комментариях, как было сделано в листинге, позволяет не удалять код отладки вплоть до последнего момента. Функция dump_array () представляет собой оболочку для функции print_r(), дополнительно выполняя лишь отмену всех завершающих HTML-дескрипторов комментариев.

Уровни выдачи сообщений об ошибках

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

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

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

Устанавливаемый по умолчанию уровень (все сообщения кроме уведомлений) указывается следующим образом:

E_ALL & ~E_NOTICE

Это выражение включает две предопределенных константы, объединенных с помощью операторов побитовых арифметических действий. Амперсанд (&) задает битовую операцию AND, а тильда (~) — битовую операцию NOT. Выражение можно прочитать так: Е ALL AND NOT E NOTICE.

Таблица. Константы, определяющие уровень сообщений об ошибках
Значение Имя Описание
1 E_ERROR Сообщения о неисправимых ошибках времени выполнения
2 E_WARNING Сообщения об исправимых ошибках времени выполнения
4 E_PARSE Сообщения об ошибках синтактисического анализатора
8 E_NOTICE Уведомления и предупреждения, что выполненные действия
могут быть ошибочными
16 E_CODE_ERROR Сообщения о сбоях запуска механизма РНР
32 E_CODE_WARNING Сообщения об исправимых ошибках в процессе запуска
механизма РНР
64 E_COMPILE_ERROR Сообщения об ошибках компиляции
128 E_COMPILE_WARNING Сообщения об исправимых ошибках компиляции
256 E_USER_ERROR Сообщения о сгенерированных пользователем ошибках
512 E_USER_WARNING Сообщения о сгенерированных пользователем
предупреждениях
1024 E_USER_NOTICE Сообщения о сгенерированных пользователем
уведомлениях
2047 E_ALL Сообщения обо всех ошибках и предупреждениях
2048 E_STRICT Сообщения об использовании устаревшихи нерекомендованных функциях; не включено в E_ALL, однако исключительно полезно при просмотре кода

Константа E_ALL представляет собой комбинацию всех типов ошибок. Ее можно заменить, связав все остальные константы битовыми операциями ИЛИ (OR,|):

E_ERROR | E_WARNING | EJPARSE | E_NOTICE | E_CORE_ERROR | E_CORE_KARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_OSER_ERROR | E_USER_WARNING | E_USER_NOTICE

Подобным же образом реализуется устанавливаемый по умолчанию уровень сообщений за исключением того, что отсутствует уровень уведомлений (константа E_NOTICE):

E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_OSER WARNING | E USER NOTICE