Как найти ошибку в своем коде?

Быстрые рекомендации.
Введение. Очень важное.
Сообщения об ошибках PHP.
Отладка и поиск ошибок в своем алгоритме.
Пример отладки.
Самое важное - знать, что ты хочешь получить.
Заключение.
Комментарии (64)

Быстрые рекомендации.
1. Убедитесь, что вы видите сообщения об ошибках, если они возникают.
Для этого надо добавить в начало скрипта 2 строчки
ini_set('display_errors',1);
error_reporting(E_ALL);

Хотя в некоторых случаях это всё равно не поможет. Тогда смотрите ошибки в логах веб-сервера.
Ещё можно добавить в файл .htaccess строчку
php_flag display_errors 1
Обязательно убрать всех собак (@) из кода!
Если апач выдаёт ошибку 500 - значит надо смотреть текст ошибки в логе ошибок веб-сервера.

2. Если возникают проблемы с функциями MySQL (например "supplied argument is not a valid MySQL result resource") - это значит, что mysql_query() выполнилась с ошибкой. Чтобы всегда быть в курсе таких ошибок, функцию mysql_query надо вызывать так:

$sql "SELECT * FROM table";
$res mysql_query($sql) or trigger_error(mysql_error()." in ".$sql);


Если используется mysqli, то перед коннектом написать 1 строчку:
mysqli_report(MYSQLI_REPORT_ERROR MYSQLI_REPORT_STRICT);

Если используется PDO, то соединяться, как написано здесь: http://phpfaq.ru/pdo#connect

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

4. При проблемах в аплоаде в первую очередь смотрите массив $_FILES (print_r($_FILES);). Описания ошибок из $_FILES['filename']['error'] есть в мануале.

5. При проблемах во взаимодействии сервера и клиента (куки, сессии, запросы)- в обязательном порядке смотреть обмен HTTP заголовками

6. Закомментируйте строчку с header("Location:"), если ищете обшибку в обработчике POST запроса

7. При отладке AJAX запросов смотрите ответ сервера в FireBug-e и его аналогах (кнопка F12 в любом браузере), вкладка Network - Preview.

8. И САМОЕ ВАЖНОЕ: запуская скрипт, смотрите не то, что показывает браузер, а ИСХОДНЫЙ HTML код!.

Получив сообщение об ошибке, вы можете его прочитать и исправить.
Если не справились - пишите на форум. При этом КОПИРУЙТЕ сообщение об ошибке, и КОПИРУЙТЕ небольшой - 3-5 строк - кусок кода, на который указывает ошибка. Повторяю - КОПИРУЙТЕ! никакой отсебятины!

Если вы всё равно не нашли ошибку - читайте дальше:

Введение. Очень важное.
Ты написал программу, а она не работает.
Вариантов ты видишь немного - либо сидеть и пытаться умственным усилием обнаружить ошибку, в сотый раз просматривая код, либо пойти на форум и попросить, чтобы там тебе нашли ошибку.
Самое интересное, что есть третий, в сто раз лучше первых двух.
Этот способ называется "Отладка программы". По-английски - debug.
Заключается он в том, чтобы заставить программу саму показать, где в ней ошибка.
Это мало того, что получится быстрее, чем спрашивать на стороне - так зачастую это единственный способ решить проблему. Единственный.
Я тебе сейчас открою страшный секрет. В мире НЕТ программистов, которые пишут код, как художники на Арбате - сел, наваял, отдал. Нету. И не будет.
Процесс написания программы - циклический: Написал кусок кода - посмотрел, как работает. Если не работает - ищем ошибки. Работает - пишем дальше.
Только так. Других вариантов нет.
Больше того. В большинстве случаев совершенно бесполезно вываливать на форум свой код, и спрашивать - "В чём ошибка?". На форуме не сидят волшебники вперемешку с телепатами. И гадалок с прорицателями - тоже нет. Поэтому отгадывать, в чём, теоретически, может быть ошибка, никто не будет. Ошибку найти может только хозяин программы. На своём сервере. Со своими настройками и опечатками. Поэтому локализовать ошибку - найти место, где она происходит, определить тип ошибки - можно только самостоятельно. А вот исправить её на форуме помогут. Если не получится самому.

Те, кто приходит к веб-программированию от дизайна, или от игр, или от нечего делать, просто не знают этой страшной тайны: Основное время программиста уходит не на написание кода. Основное время программиста уходит на поиск ошибок и отладку. Это не шутка. Это правда. И если вы решили заняться программированием, то вам придётся искать ошибки точно так же, как это делают все остальные.
К сожалению, очень много людей приходит к PHP вообще без опыта программирования и, как следствие - никогда не слышали об отладке.
А это и есть самое главное в программировании - умение искать ошибки.
И мы с тобой сейчас будем учиться их искать.

Программа не работает. Что можно сделать в этом случае?

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

Пояснение: Очень многие люди не понимают, что такое сообщение об ошибке. В основном эти люди делятся на две категории. Первая считает, что сообщения об ошибках - это блажь разработчиков языка, надоедливый сервис, сделанный для того, чтобы программисту было не скучно. И избавляться от сообщений надо любыми доступными способами. Вторая категория не выросла из школьного возраста и воспринимает не смысл ошибки, а лишь сам факт. Принимают пхп за стервозного завуча, который ругает не по делу, а абстрактно, за то, что оболтус. То есть, факт появления ошибки вызывает у этих людей только негативные эмоции, а в смысл они даже не пытаются вчитываться.

Это чудовищные заблуждения. Сообщения об ошибках - это ПОМОЩЬ! Это громадная помощь программисту. Как ей воспользоваться, мы рассмотрим ниже.


Даже самый рабочий код, которому ты на 100% доверяешь, и который на соседней машине работает, как часы, может выдавать сообщение об ошибке. Причин тому может быть бесконечное множество. Это и такой распространенный случай, как отсутствие прав доступа к файлам, и такие экзотические, как запрещение провайдером выполнения самых распространенных и безобидных функций.

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

Во-первых, надо выяснить, выводятся ошибки на экран или пишутся в лог. Обычно, домашний, или тестовый сервер настраивается так, чтобы ошибки выводились на экран. Рабочий же сервер, с сайтом в публичном доступе ОБЯЗАТЕЛЬНО должен быть настроен так, чтобы ошибки не выводились на экран (поскольку посетителю они все равно ничего не скажут, а программист их не увидит), а писались в лог, где программист их увидит.
Если ты не уверен, и не знаешь, где посмотреть, а ошибку найти надо срочно, то напиши в самом начале скрипта две строчки
ini_set('display_errors',1);
error_reporting(E_ALL ^E_NOTICE);

Эти две строки заставят выводить сообщения обо всех критических ошибках на экран.
Если никаких ошибок не выведется, надо написать
error_reporting(E_ALL);
Это очень сильно поможет, показав несуществующие переменные и другие мелкие ошибки, которые обычно игнорируются, но от которых может зависеть работоспособность программы.
ВАЖНО! В случае ошибки синтаксиса, по очевидным причинам, установка с помощью ini_set не сработает.
Поэтому лучше на неё не надеяться, а либо исправить в php.ini (или в .haccess добавить строчку php_flag display_errors 1), либо искать ошибку в логе.

Во-вторых, убедись, что в коде отсутствуют символы '@' перед именами функций. Этот запрещает вывод сообщения об ошибке. Хорошенькое дело! Ты ошибку ищешь-ищещь, а сам же своей программе рот заткнул.

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

При возникновении проблем с функциями mysql (supplied argument is not a valid MySQL result resource) под строкой, где произошла ошибка, обязательно надо вывести на экран mysql_error() и сам запрос - для визуального контроля и копирования на форум.

При работе с изображениями, чтобы увидеть сообщение об ошибке, обязательно надо догадаться отключить вывод заголовка, говорящего браузеру, что дальше идет картинка.
При аплоаде в первую очередь смотрите массив $_FILES.
При проблемах во взаимодействии сервера и клиента - в обязательном порядке смотреть обмен HTTP заголовками
И всегда смотрите не то, что показывает браузер, а ИСХОДНЫЙ HTML код!

Допустим, сообщение об ошибке появляется, и ты его получил. Что делать дальше? Очень просто - прочесть и исправить. Если не хватает знания английского языка, то стоит либо воспользоваться переводчиком, либо взять значащую часть этого сообщения и запросить Google. 90% вероятности, что кто-то с такой ошибкой уже сталкивался, и ты тут же прочтешь ответ.
Если же не нашел, то задай вопрос в форуме, точно скопировав небольшой (3-5 строк) кусок кода, в котором произошла ошибка, точно указав строку, о которой говорится в сообщении об ошибке, а так же - самое главное! - само сообщение об ошибке.
Согласись, что с такой информацией тебе на форуме помогут гораздо скорее и качественней?

Отладка и поиск ошибок в своем алгоритме.
Но бывает так, что программа не вызывает ошибок, но все равно не работает, или работает не так, как надо.
Тут уже виноват или алгоритм или какие-то внешние факторы.
Однако и тут можно найти место, где происходит ошибка.
Но только при одном условии.
что ты четко представляешь, что делает твоя программа, каждая функция, каждая строка в ней. Потому, что если ты представляешь, то можешь предсказать, какие значения должны иметь переменные на каждом этапе выполнения.
А дальше все ОЧЕНЬ просто!
Во-первых, надо разделить программу на логические блоки.
Допустим, скрипт выводит форму, получает ее, и записывает данные в базу. ТРИ шага! И в любом из них может быть ошибка, приводящая к тому, что данные в базу не записываются.
Надо проконтролировать на каждом из участков - все ли переменные имеют то значение, которое ожидается.
Программа ведь работает с переменными.
Как проверить?
Выводить все используемые переменные на экран! И визуально контролировать их содержимое.
Всего-то лишь написать проблемных местах var_dump($var) и выяснится, что переменная-то пустая!
И уже можешь пойти на форум не с вопросом "у меня вот код на 100 строк, где ошибка?", а "я написал функцию, но почему-то, когда обращаюсь в ней к переменным, они все пустые". или "из формы не передаются переменные".
Между этими двумя способами задания вопросов - пропасть.
Первый не может тебе помочь никак. Ты, собственно, и сам не знаешь, что у тебя за проблема. А при втором ты уже знаешь проблему, и, если сам не справился с ее решением, то можешь задать на форуме конкретный вопрос.

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

Пример отладки.
Из html формы передаются чекбоксы с именами c_1, c_1, c_3... c_10
В скрипте мы пытаемся в цикле вывести
for ($i=1$i<11$i++) {
  echo 
$_POST['с_$i'];
}

скрипт ничего не выводит.
Начинаем отлаживать.
Сначала смотрим в исходный код html страницы. соответствует ли она стандартам?
Допустим, соответствует. Значит, проблема не в форме.
Далее, проверяем в скрипте - а есть ли такая переменная, к которой мы обращаемся - массив $_POST?
пишем

echo '<pre>';
var_dump($_POST);

Убеждаемся в том, что массив есть и все элементы на месте. Значит, проблема не в передаче.
Значит, мы как-то неправильно обращаемся к массиву.
обращаемся мы к нему так: $_POST['с_$i']
Надо проверить - а во что превращается 'с_$i'?
делаем echo 'с_$i'; и видим... совсем не то, что ожидали увидеть.
И вот теперь уже идем либо читать документацию про строки в пхп (что предпочтительнее), либо - на форум, с вопросом "почему у меня переменная не заместилась своим значением". Каковой вопрос будет гораздо лучше звучать, чем "у меня форма не работает".
Понятно?

Следует понимать, что здесь приведён пример, Нереальный. Показан алгоритм действий.
В реальности, при error_reporting(E_ALL); PHP сразу же показал бы, что индекс массива у вас неправильный.

Самое важное - знать, что ты хочешь получить.
Примерно половина вопросов на форумах вызвана тем, что человек делает что-то...НЕ ЗНАЯ, что именно!
Самый гениальный вопрос всех времён и народов: "у меня база съела все переводы строк из текстарии".
Человек просто не дал себе труд посмотреть, как будет выглядеть HTML, который он хочет получить, и решил, что переводы строк съела база.
И так во всём.
Непризнанный гений строит сложный SQL запрос, а когда его спрашивают, как запрос должен выглядеть - он только хлопает глазами. ВСЕГДА СНАЧАЛА составьте запрос руками и выполните в консоли или phpmyadmin! А после того, как получили нужный запрос и отладили - милости просим, составляйте его на пхп.
Работа с удалённым хостом через сокет по протоколу HTTP - то же самое! Сначала научитесь выполнять все команды руками, посмотрите ответы сервера глазами, а потом моделируйте этот диалог в пхп.
Работа с яваскриптом по тому же методу описана в факе "на танке"

Запомните - на пхп вы работаете только со СТРОКАМИ! HTML страница, которую вы создаёте скриптом - это для пхп всего лишь набор строк! Ему без разницы, что в этом наборе - теги img, script или frame. Пхп за вас не сделает переводы строк, не нарисует яваскрипт. Если вы не знаете яваскрипта - то не пытайтесь создавать программу на нём с помощью PHP.
Открывая соединение с удалённым хостом, вы посылаете строку в сокет, вы получаете строку из сокета. Пхп ничего не понимает в этих строках и за вас диалог вести не будет! Это ВЫ должны чётко понимать, что вы хотите послать в сокет, и что получить! Поэтому возьмите программу telnet, соединитесь с нужным хостом и пробуйте сначала САМИ сделать то, что хотите заставить сделать пхп.
Если у вас не работает скрипт с сокетами - бегом в телнет смотреть, что происходит!
SQL запрос - это СТРОКА. Вы должны себе чётко представлять, какой запрос получится в результате вашего хитроумного пхп-кода! Сервер БД не понимает конструкций intval, date, mktime и так далее! Это всё пхп-код. Результатом которого будет являться строка корректного SQL запроса. прежде, чем писать пхп код, вы должны ЧЁТКО СЕБЕ ПРЕДСТАВЛЯТЬ, КАК ДОЛЖЕН ВЫГЛЯДЕТЬ SQL ЗАПРОС В РЕЗУЛЬТАТЕ!
Если у вас не выполняется SQL запрос 0 выводите его на экран и смотрите - что нагородили своим скриптом!

Заключение.
Отладка - главное занятие программиста.
Отладка - единственный и самый мощный способ найти ошибку в программе.
Отладка состоит из двух основных компонентов:
1. Максимально упрощать пример. Если у вас не работает программа, которая рисует форму,получает данные, записывает данные формы в базу и выводит их снова, то разбейте программу на составляющие и выполняйте по очереди.
Если у вас не работает сложная подпрограмма определения работоспособности кук - напишите сначала тест в две строчки чтобы убедиться, что вы хотя бы можете выставлять и читать куку.
2. Вывод отладочной информации.
Проверяйте значение КАЖДОЙ переменной! Каждого значения, возвращаемого функцией!
Не работает локейшен? Выведите его на экран и скопируйте в браузер!
В файл записывается пустая строка? проверяйте составляющие этой строки на каждом этапе ее создания и выводите на экран!
Убедились, что на экран выводится? Тренируйтесь писать в файл, на тестовой строке! Забитой прямо в скрипт! Уменьшайте количество неизвестных!
И всегда смотрите не то, что показывает браузер, а ИСХОДНЫЙ HTML код!

Надеюсь, что я смог хотя бы немного объяснить принципы этого занятия.
Удачной отладки.