Внимание! Сайт переехал на новый домен sayt-sozdat.ru. Пожалуйста, обновите страницы закладок с новыми URL
×
Закрытие
10
×

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

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

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

Устанавливаем графический редактор GIMP

  1. Выбор графического редактора
  2. Устанавливаем программу GIMP
  3. Устанавливаем Руководство пользователя

Здравствуйте уважаемый посетитель!

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

В статье Устанавливаем бесплатный графический редактор GIMP речь пойдет о бесплатной программе GIMP, которая позволяет в полной мере решать вопросы по созданию элементов дизайна веб-страниц. И будет показано, как ее установить на локальный компьютер.

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

Для тех же, кто хочет заниматься дизайном на платном Adobe Photoshop (фотошоп), здесь также упомянут и такой вариант, основанный на использовании продления льготного бесплатного периода фотошопа на неопределенное время...

Cайт на практическом примере

Текущее состояние создаваемого сайта

Здесь можно посмотреть текущее состояние сайта, создаваемого в рамках цикла статей Самописный сайт с нуля своими руками.

Исходные файлы данного сайта можно скачать из прилагаемых к статьям дополнительных материалов.

Вы здесь: Главная → Сборник статей → Обработка ошибок → Перехват и обработка не фатальных ошибок PHP


Автор: / Дата:

Перехват и обработка не фатальных ошибок PHP

Перехват и обработка не фатальных ошибок PHP

Здравствуйте, уважаемый посетитель!

Сегодня, продолжая работу над созданием системы обработки ошибок, займемся теперь не фатальными ошибками PHP (далее по тексту - ошибками). Которые в отличие от ранее рассмотренных - фатальных, сами по себе не оказывают серьезного влияния на функционал и отображение веб-страниц, но все-равно требуют определенных действий.

Содержание


  • Перехват и идентификация ошибок
  • Запись информации об ошибках в журнал
  • Проверка сохранения отчета об ошибках
  • Исходные файлы сайта

Перехват и идентификация ошибок


Для перехвата ошибок, отличных от фатальных существует другая встроенная функция PHP set_error_handler(), которая задает в качестве их обработчика определенную пользователем функцию, позволяющую во время выполнения скрипта, не обрывая его работу, регистрировать возникшую ошибку.

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

  • $errno - тип (уровень) ошибки в виде целого числа;
  • $errstr - сообщение об ошибке;
  • $errfile — имя файла;
  • $errline — номер строки;
  • $errcontext — массив всех переменных, существующих в области видимости, где произошла ошибка.

Более подробно с описанием данной функции можно ознакомиться в соответствующем разделе Справочника по PHP.

скриншот 79

В нашем случае для описания возникшей ошибки будем использовать четыре параметра: два обязательных - $errno и $errstr, и два необязательных - errfile и $errline. Что вполне достаточно для последующего анализа и устранения возникновения подобных ситуаций.

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

  1. <?php

  2. //----Перехват и обработка не фатальных ошибок PHP----

  3. function errors_handler($errno, $errstr, $errfile, $errline){ //Пользовательская функция обработчика ошибок PHP

  4. $errors = array( //Формирования массива констант ошибок

  5. E_WARNING => 'E_WARNING',

  6. E_NOTICE => 'E_NOTICE',

  7. E_CORE_WARNING => 'E_CORE_WARNING',

  8. E_COMPILE_WARNING => 'E_COMPILE_WARNING',

  9. E_USER_ERROR => 'E_USER_ERROR',

  10. E_USER_WARNING => 'E_USER_WARNING',

  11. E_USER_NOTICE => 'E_USER_NOTICE',

  12. E_STRICT => 'E_STRICT',

  13. E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',

  14. E_DEPRECATED => 'E_DEPRECATED',

  15. E_USER_DEPRECATED => 'E_USER_DEPRECATED'

  16. );

  17. $date = date ("Y-m-d G:i:s"); //Получение даты и времени возникновения ошибки

  18. $url = $_SERVER['REQUEST_URI']; //Получение URL страницы, при формировании которой произошла ошибка

  19. echo "$date $errors[$errno] $errstr в файле $errfile в $errline строке (URL: $url)"; //Сформированное сообщение об ошибке

  20. }

  21. set_error_handler('errors_handler'); //Регистрация пользовательской функции

  22. ?>

Рис.1 Пользовательская функция обработчика ошибок PHP

Пользовательская функция обработчика errors_handler() (поз.3÷20) здесь регистрируется, как было выше сказано, встроенной функцией PHP set_error_handler() (поз.21).

А в самом обработчике для получения необходимых данных, дополнительно, с помощью массива соответствия констант определяется тип ошибки (поз.4÷16). Это желательно сделать, так как по умолчанию аргументом errno информация об ее уровне передается только в виде целого числа, что не очень удобно при анализе.

А кроме того, для точного определения момента возникновения ошибки определяется дата, время ее регистрации (поз.17) и URL страницы, при генерации которой она произошла (поз.18).

В результате чего формируется сообщение с описанием ошибки (поз.19) с указанием: даты и времени возникновения ($date), типа в виде константы ($errors[$errno]), сообщения, привязанного к данному типу ($errstr), имя файла ($errfile) и номер строки ($errline), в которой она произошла, а также URL страницы ($url).

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

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

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

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

Например, добавим инструкцию, в которой выполняется недопустимое действие, предусматривающее деление на ноль во фрагмент PHP-кода, расположенный в начале шаблона главной страницы в файле index.php. После чего откроем, или обновим какую-нибудь страницу сайта.

Проверка перехвата и идентификации ошибки

Рис.2 Проверка перехвата и идентификации ошибки

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

  • дата - 2019-12-09;
  • время - 20:00:43;
  • уровень - E_WARNING;
  • сообщение - Division by zero;
  • имя файла - index.php с директорией E:\OSPanel\domains\newsite.local\;
  • номер строки - 54;
  • URL страницы - /kontakty.html.

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

Запись информации об ошибках в журнал


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

Так как в создаваемой системе предполагается ведения не одного, а нескольких журналов, распределенных по отдельным видам, то для их размещения в корне сайта создадим отдельный каталог logs. Где в дальнейшем будем располагать и все остальные файлы, относящиеся к протоколированию ошибок.

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

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

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

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

Что касается PHP-функции, которая будет использована для записи данных в файл, то в данном случае применим функцию file_put_contents. Так как здесь отсутствует какя-либо многозадачность. И такое решение позволяет реализовать необходимый функционал значительно проще и компактней, чем если бы для этого использовался набор аналогичных функций: fopen(), flock(), fwrite() и fclose().

Ниже показан ранее созданный обработчик c добавлениями, которые обеспечивают запись сообщения о возникшей ошибки в лог-файл с ограничением его размера в зависимости от заданного значения максимального количества сообщений (фрагмент с добавленным кодом выделен светлым фоном).

  1. <?php

  2. //----Перехват и обработка ошибок PHP----

  3. function errors_handler($errno, $errstr, $errfile, $errline){ //Пользовательская функция обработчика ошибок PHP

  4. $errors = array( //Формирования массива констант ошибок

  5. E_WARNING => 'E_WARNING',

  6. E_NOTICE => 'E_NOTICE',

  7. E_CORE_WARNING => 'E_CORE_WARNING',

  8. E_COMPILE_WARNING => 'E_COMPILE_WARNING',

  9. E_USER_ERROR => 'E_USER_ERROR',

  10. E_USER_WARNING => 'E_USER_WARNING',

  11. E_USER_NOTICE => 'E_USER_NOTICE',

  12. E_STRICT => 'E_STRICT',

  13. E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',

  14. E_DEPRECATED => 'E_DEPRECATED',

  15. E_USER_DEPRECATED => 'E_USER_DEPRECATED'

  16. );

  17. $date = date ("Y-m-d G:i:s"); //Получение даты и времени возникновения ошибки

  18. $url = $_SERVER['REQUEST_URI']; //Получение URL страницы, при формировании которой произошла ошибка

  19. $error_message = "$date $errors[$errno] $errstr в файле $errfile в $errline строке (URL: $url)\n"; //Сформированное сообщение об ошибке

  20. $max_message = 100; //Максимальное количество сообщений в лог-файле

  21. $filename = 'logs/warning_php.txt'; //Имя файла с директорией

  22. if (file_exists($filename)) { //Если файл существует

  23. $file_data = file($filename); //Считываем данные из файла в массив

  24. if (count($file_data) >= $max_message){ //Если количество элементов в массиве достигает максимального значения

  25. unset($file_data[0]); //Удаляем первый по списку элемент массива

  26. $clean_data = implode("", $file_data); //Преобразуем данные массива в строку

  27. file_put_contents($filename, $clean_data, LOCK_EX); //Записываем преобразованные данные с удаленным сообщением обратно в файл

  28. }

  29. }

  30. file_put_contents($filename, $error_message, FILE_APPEND | LOCK_EX); //Добавляем сообщение об ошибке в лог-файл (в конец файла). Если файла не существует, будет создан

  31. }

  32. set_error_handler('errors_handler'); //Регистрация пользовательской функции

  33. ?>

Рис.3 Обработчик ошибок PHP с сохранением сообщения в журнале

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

1. Подготовка первичных данных.

  • $error_message (поз.19) - сформированное сообщение об ошибке;
  • $max_message (поз.20) - максимальное количество сообщений в лог-файле;
  • $filename (поз.21) - имя файла с директорией;

2. Запись (добавление) сообщения в конец файла при блокировке его на время записи (поз.30). При этом, если файл не существует, он автоматически создается. Для обеспечения нужного режима используются следующие дополнительные параметры функции file_put_contents:

  • FILE_APPEND - данные записываются в конец файла вместо того, чтобы его перезаписать;
  • LOCK_EX - блокировка файла на время записи.

3. Освобождение места в лог-файле для записи нового сообщения в существующем файле, в котором количество строк достигло максимальное значение.

  • file($filename) (поз.23) - получение данных из файла в виде массива.
  • unset($file_data[0]) (поз.25) - удаление первого по списку элемента массива, соответствующего первой строке файла;
  • implode("", $file_data) (поз.26) - преобразование данных массива в строку;
  • запись (перезапись поверх прежних данных) преобразованных данных с удаленным сообщением обратно в файл с блокировкой файла на время записи (флаг LOCK_EX) (поз.27).

Таким образом при записи нового сообщения в случае, если размер журнала не достиг максимальной величины, происходит простое ее добавление в конец существующего файла (поз.30). Во время первой записи, при отсутствии файла, он создается с последующей записью.

В случае же, если файл существует (поз.22) и количество строк достигло максимальной величины (поз.24), то перед тем, как будет произведена запись нового сообщения по предыдущему пункту, из файла будет удалена первая по списку строка, соответствующая самому старому по времени сообщению (поз.25÷27).

На этом обработку ошибки в части записи сообщение в журнал, мы закончили. Осталось только проверить результат.

Проверка сохранения отчета об ошибках


Для проверки работы механизма сохранения сообщений, снова откроем или обновим какую-нибудь страницу сайта. И тем самым мы вызовем ту же самую ошибку, которую ранее преднамеренно добавили в PHP-код. А именно: ошибочное действие, предусматривающее деление на ноль.

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

Создание лог-файла при первой записи

Рис.4 Создание лог-файла при первой записи

Если же открыть этот текстовый файл, то в нем должна отобразиться первая запись с сообщением об ошибке.

Первое сохраненное сообщение

Рис.5 Первое сохраненное сообщение

Далее проверим ограничение максимального размера лог-файла. Для этого временно уменьшим соответствующее значение переменной $max_message (рис.3, поз.20), скажем до величины 5. После чего несколько раз, превышая максимальное значение, обновим страницу.

При корректной работе обработчика количество сообщений (строк) в файле после выполненных операций должно равно установленному значению 5.

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

Проверка максимального количества сообщений

Рис.6 Проверка максимального количества сообщений

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

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


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

Исходные файлы сайта


Знак папкиИсходные файлы сайта с обновлениями, которые были сделаны в данной статье, можно скачать из прилагаемых дополнительных материалов:

  • Файлы каталога www
  • Таблицы базы данных MySQL

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

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

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

С уважением, Николай Гришин


Комментарии


Если у Вас возникли вопросы, или есть какие-либо пожелания по представлению материала, либо заметили какие-нибудь ошибки, а быть может просто хотите выразить свое мнение, пожалуйста, оставьте свои комментарии. Такая обратная связь очень важна для возможности учета мнения посетителей.

Буду Вам за это очень признателен!