Обработка ошибок с помощью trigger_error() и set_e

\\n"; echo "$file ($line)"; } set_error_handler('my_error_handler'); if (!file_exists('/home/mysite/news.txt')) { trigger_error('News file not found'); } ?> Результат обработки данного файла будет таким: Произошла ошибка News file not found (1024) /home/mysite/myerrortest.php (12) Теперь у нас есть функция, которая получает данные обо всех происходящих ошибках. Подумаем, как мы можем это использовать. Будем обрабатывать ошибки уровней E_ERROR E_WARNING E_NOTICE E_USER_ERROR E_USER_NOTICE Первые три ошибки в хорошей законченной программе не должны происходить вообще, поэтому о них мы будем только сообщать пользователю выводом текста ошибки на экран. Так можно работать, пока скрипт в состоянии разработки, затем сообщения о них можно либо отключить, либо записывать в log-файл. Что касается остальных двух - как Вы уже догадались - они могу там пригодиться. Мы сами будем вызывать ошибки этих уровней в случае необходимости. Допустим - ошибки уровня E_USER_ERROR - будем вызывать в случае, когда сообщение об ошибке должно попасть в log-файл и быть отправлено на e-mail администратору (например - ошибка при выполнении SQL запроса, или отсутствии парв доступа к необходимому файлу). Ошибки уровня E_USER_NOTICE будут вызываться при возникновении "лёгких" ошибок (например - пользователь некорректно заполнил форму, или запросил из базы несуществующую запись). Теперь наша функция обработки ошибок будет выглядеть примерно так: // Немного предварительных настроек // устанавливаем режим отображения ошибок // отображать все ошибки, кроме E_NOTICE error_reporting (E_ALL & ~E_NOTICE); // эта константа отвечает за // включение/выключение режима отладки // во время отладки - сообщения не отсылаются // по почте, а просто печатаются на экран define('DEBUG', 0); // это глобальная переменная, в которой // будет храниться сообщение, которое // должен видеть пользователь $MSG = ''; // e-mail разработчика, куда отправлять ошибки define('ADM_EMAIL','admin@example.com'); // log-файл define('LOGFILE','/home/mysite/mylog.log'); // разница во времени с сервером (в секундах) define('TIMEOFFSET', 0); // сама функция function my_error_handler($code, $msg, $file, $line) { // глобальная переменная, в которую будет // записываться сообщение об ошибке. global $MSG; // пропускаем ошибки уровня E_NOTICE // и игнорируем ошибки, если режим сообщения об ошибках отключен if ( ($code == E_NOTICE) or (error_reporting() == 0) ) { return; } // если мы вызвали ошибку уровня E_USER_NOTICE - просто // записать текст ошибки в глобальную переменную $MSG // и прекратить выполнение функции if ($code == E_USER_NOTICE) { $MSG = $msg; Return; } // если ошибка уровня E_ERROR - печатаем текст ошибки // и завершаем выполнение скрипта if ($code == E_ERROR) { die ('
ERROR: '.$msg.'
In '.$file.' (line '.$line.')
'); } // если ошибка уровня E_WARNING - печатаем текст ошибки // и прекращаем выполнение функции if ($code == E_WARNING) { echo '
WARNING: '.$msg.'
In '.$file.' (line '.$line.')
'; Return; } // если ошибка уровня E_USER_ERROR if ($code == E_USER_ERROR) { // записываем в переменную $MSG текст, о том что произошла ошибка, // причины сообщать не будем, только сообщим что подробности // отправлены на e-mail кому следует. $MSG = 'Критическая Ошибка: действие выполнено небыло.
Сообщение об ошибке было отправлено разработчику.'; // подробности записываем в переменную $text $text = $msg.'
'.'Файл: '.$file.' ('.$line.')'; // Если константа DEBUG установлена в 1 - печатаем информацию об // ошибке на экран, если нет - отправляем текст ошибки почтой // функция error_mail() и пишем в log - функция error_writelog() if (DEBUG == 1) { error_print($text); } else { error_mail($text); error_writelog($text); } Return; } } // устанавливаем обработчик set_error_handler('my_error_handler'); Теперь описываем служебные функции // ф-я печатает ошибку на экран function error_print($text) { echo $text.'

'; } // ф-я отправляет ошибку почтой function error_mail($text) { $text = str_replace("
", "\\n", $text); $info = 'Время: '.get_datetime()."\\nRemote IP:".get_ip()."\\n"; mail(ADM_EMAIL, "Error reporting", $info.$text); } // ф-я пишет ошибку в лог function error_writelog($text) { $text = str_replace("
", "\\t", $text); if (@$fh = fopen(LOGFILE, "a+")) { fputs($fh, get_datetime()."\\t".get_ip()."\\t".$text."\\n"); fclose($fh); } } // получаем время, с учётом разницы во времени function get_time() { return(date("H:i", time () + TIMEOFFSET)); } // получаем дату, с учётом разницы во времени function get_date() { return(date("Y-m-d", time () + TIMEOFFSET)); } // получаем дату и время, с учётом разницы во времени function get_datetime() { return get_date().' '.get_time(); } // получаем IP function get_ip() { return($_SERVER['REMOTE_ADDR']); } И наконец пример использования // ф-я записывает новость в файл function write_news($title, $text) { $news_file = '/home/mysite/news.txt'; // проверяем наличие заголовка - ошибка не критическая if (!trim($title)) { // для того чтобы определить что функция завершилась // неудачей - необходимо вернуть false. Функция // trigger_error() - возвращает true, мы будем // возвращать её инвертированный результат return !trigger_error('Необходимо указать заголовок новости'); } // проверяем наличие текста новости - ошибка не критическая if (!trim($text)) { return !trigger_error('Необходимо указать текст новости'); } // проверяем наличие файла в который будем писать // если файл не найден - возникает критическая ошибка if (!file_exists($news_file)) { return !trigger_error('Файл базы новостей не найден!', E_USER_ERROR); } // ...тут предварительная обработка данных... // записываем новость $fh = fopen($news_file, "a+"); fputs($fh, $title."\\t".$text."\\n"); fclose($fh); // если всё нормально - функция возвращает true return true; } // пытаемся записать новость // эти данные могут приходить из web-формы $res = write_news("Моя новость", "Текст моей новости"); if ($res === false) { // если вернулся false - печатаем ошибку echo $MSG; } else { // если всё в порядке - можно сообщить об этом // а лучше отфорвардить пользователя куда-нибудь. echo 'Новость была добавлена'; } Для того чтобы пример заработал - просто скопируйте в PHP-файл три предыдущих блока кода. Не забудьте установить права доступа на log-файл 777 для того чтобы скрипт мог с ним работать, прописать правильные пути и указать свой e-mail. Вы можете включить режим отладки установкой переменной DEBUG в 1.

Скачать файл txt fb2