PDA

Просмотр полной версии : [Статья] Обработка ошибок в Php


Ch3ck
09.07.2006, 19:16
Статья предназначена для начинающих, так что кто "очень разбирается" могёте не читать...
Хм, решил написать небольшую статью о ошибках в PHP. Выкладываю статью в этот раздел, так как чаще всего тут задаются вопросы данного типа. Итак... Поехали((це)Гагарин)...
Ошибки в программирование можно разделить на несколько категорий:
1)Синтаксические ошибки. Тут само собой понятно, что возникают вследствии неверного синтаксиса программы, и не позволяет транслятору правильно интерпертировать код программы.
2)Логические ошибки. Самые "говнястые". В большинстве случаев сообщение об ошибке не выводится, но программа делает не то, для чего она предназначена.
3)Ошибки окружения. Возникают в результате внешних факторов.

В PHP сделали очень информативное отображение ошибок, чтобы программисту(типа Кодера Алёши) было проще их отлаживать.
Все ошибки выводятся по шаблону:
Уровень ошибки: сообщение, имя_файла, строка.
В зависимости от стерпени сложности ошибки, их можно разделить на 2 вида: Это "parse error" - синтаксические,и некому не нравящиеся "fatal error" - неисправимые ошибки, завершающие выполнение сценария программы. Ну конечно,самые частые это - "warnings" - предупреждения и "notices" - "замечания". При возникновении последних двух ошибок выполнение сценария продолжается, но всё равно следует обращать на них внимание и исправлять по возможности.
Разумеется, PHP предоставляет средства для регулирования того, информацию о каких ошибках следует выводить браузеру. Это зависит от параметра error_reporting, значение по умолчанию которого задается в конфигурационных файлах, а для каждого отдельного сценария его можно определять при помощи одноименной процедуры, единственный параметр которой - целое число - получается следующим образом. Каждому типу ошибок соответствует некоторые значение. Так, 1 соответствует неисправимым ошибкам, 2 - предупреждениям, 4 - синтаксическим ошибкам, а 8 - уведомлениям. Суммируя коды типов ошибок, информацию о которых следует выводить, получаем параметр этой процедуры. Так, например, чтобы вообще не выводить никаких сообщений, следует написать error_reporting(0), а чтобы показывать неисправимые ошибки и предупреждения, параметр функции следует установить равным 3 (1+2).
На мой взгляд при отладке какой-либо программы следует установить максимальный уровень сообщений. Так же можно заменить все стандартыные сообщения, на более "приятные" глазу, например:
if(mysql_connect($dbhost, $dbuser, $password)) {
/* тут код работы с БД */
} else {
echo "<center><H4>Произошла ошибка. Пожалуйста, повторите попытку позже.</H4></center>\n";
}
Так же можно вместо выдачи (или вместе с выдачей) ошибки отправить письмо (icq-msg, sms :)) администратору с указанием на ошибку, время возникновения и урл, при котором она возникла, что поможет ее оперативно устранить.
Иногда бывает полезно просто подавить сообщение об ошибке при отказе какой-либо функции. Для этого перед ее именем следует поставить оператор @:
if(@mysql_connect($dbhost, $dbuser, $password)).
Можно также создать целый набор собственных страниц с сообщениями об ошибках и при их возникновении переадресовывать пользователя в нужном направлении. Тут можно использовать два способа. Если браузеру еще не переданы заголовки страницы, следует воспользоваться функцией header: header("Location:error.html"),
в противном случае можно прибегнуть к средствам javascript:
echo "<script>location='error.html'</script>";.
Ещё удобной функцией в PHP является логирование ошибок.
Для записи сообщений об ошибках PHP предоставляет удобное средство - функцию error_log. Она принимает 2 обязательных параметра и 2 необязательных. Первый - сообщение об ошибке, которое будет записано в журнале. Второй параметр определяет место, куда будет направлено сообщение - это могут быть логи веб-сервера (код 0), электронная почта (1), удаленный отладчик (2) либо какой-либо внешний файл (3). Третья переменная указывает имя файла, email-адрес либо параметры отладчика, в зависимости от значения второго параметра. Так, например, чтобы передать сообщение узлу host.ru на порт 31337, следует вызвать функцию со следующими параметрами: error_log("Error message", 2, "host.ru:31337").
Для записи сообщений об ошибках удобно реализовать следующую функцию:
function logit($msg) {
$date=date("Y-m-d");
$time=date("H:i");
error_log("[$date $time] $msg\n", 3, "log.txt"); }

При помощи настроек php можно также добиться того, чтобы все сообщения об ошибках направлялись в сокет с удаленным отладчиком. За это по существу отвечают три параметра: debugger.host="узел", debugger.port=порт и debugger.enable=true/false.

Основная задача - создать программу, которая слушала бы указанный в настройках порт на определенном хосте и записывала все сообщения (либо делала что-то другое). Собственно, если ты немного умеешь программировать, тебе не составит труда написать такую программку под любую платформу (хотя бы на Perl или C++). Чтобы включить в каком-либо сценарии работу с удаленным отладчиком, следует воспользоваться функцией debugger_on("хост"). Каждое сообщение об ошибке, передаваемое отладчику, достаточно информативно для установления ее причины и местоположения.
Вот почитайте-ка...
_http://php.rinet.ru/manual/sv/function.error-log.php
_http://php.rinet.ru/manual/sv/function.error-reporting.php
_http://php.rinet.ru/manual/sv/function.set-error-handler.php
Так же не забывайте когда пишете программы которые предназначены для "долгого" выполниния например брутфорс, то не забывайте перед началом сценария воткнуть в код
set_time_limit(0);.
И ещё забыл часто бывает что вылетает такая ошибка:
"Undefined function" и новички в большинстве случаев не могут разобраться в чем дело - так вот, следите за очепятками...тьфу, опечатками.
И помните... Ошибки в программах допускают даже проффы... :cool:

Dracula4ever
09.07.2006, 20:14
Я вижу ты спец в PHP.
Помоги мне с этим кодом:

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
$connection = socket_connect($socket,'irc.antichat.ru',7771)
socket_write($socket,"USER BLA BLA :BLA\r\n");
socket_write($socket,"NICK MyFirstSocket \r\n");
socket_write($socket,"JOIN #antichat \r\n");

r0
09.07.2006, 20:47
а как же strict'ы ? :) или мы на 5ой верси не программируем? :))

Ch3ck
09.07.2006, 21:00
2 r0cha! до пятой не как руки не дойдут... хотя во много удобней 4-ки :)

2 dracula4ever я не спец. :) и чего имеено еадо? или чего у тебя с этим кодом не получается?!

SMiX
09.07.2006, 21:50
Я вижу ты спец в PHP.
Помоги мне с этим кодом:
Ты про пинг забыл наверное. На некоторых серверах сначала нуно ответить на пинг понгом, а потом идентифицироваться и т.п.