Лучшая практика для обработки ошибок с использованием PDO

Проблема:

Поиск наилучшей практики для обработки ошибок с использованием PDO. Варианты, которые я нашел на сайтах, SO, книги и т. Д.

  1. Большое количество веб-сайтов говорят, что вы должны эхо-сообщения об ошибках в своем блоке catch .
  2. Большое количество пользователей на SO говорят, что вы никогда не должны эхо-сообщения об ошибках из-за рисков безопасности.
  3. Другие рекомендуют протоколировать его в файл журнала вне корня документа.
  4. Некоторые используют обработку ошибок для регистрации в таблице SQL.

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

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

 display_errors = On display_startup_errors = On error_reporting = -1 log_errors = On 

Или если доступ к файлу php.ini недоступен:

 error_reporting(-1); ini_set("display_errors", 1); 

И в производственной среде :

 display_errors = Off display_startup_errors = Off error_reporting = E_ALL log_errors = On 

Или если доступ к файлу php.ini недоступен:

 error_reporting(0); 

Пример подключения к базе данных в рабочей среде .

Код:

 <?php // Error handling error_reporting(0); // Get credentials from outside document root require_once('../settings.php'); // Tests connection to database try { $dbh = new PDO( sprintf( 'mysql:host=%s;dbname=%s;port=%s;charset=%s', $settings['host'], $settings['name'], $settings['port'], $settings['charset'] ), $settings['username'], $settings['password'] ); // Prevents emulated prepares and activates error handling // PDO::ERRMODE_EXCEPTION $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } // Catches errors raised by PDO catch (PDOException $e) { // Prints error messages to file file_put_contents('/home/ubuntu/errors.log', 'Error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); // Shows generic error message to user header('Location: 404.php'); exit; } ?> 

Вопрос:

  • Какова наилучшая практика для обработки ошибок в PHP?
  • Какова наилучшая практика для обработки ошибок в блоке catch?

Solutions Collecting From Web of "Лучшая практика для обработки ошибок с использованием PDO"

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

Существует также одно неверное предположение о недоступности php.ini: вы всегда можете установить любую директиву конфигурации, используя функцию ini_set (). Таким образом, здесь нет ни одной причины при установке error_reporting на катастрофический уровень 0.

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

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

Что вы думаете о себе? Имеет ли смысл показывать сообщения об ошибках системы пользователю? Имеет ли смысл показывать вредоносным пользователям внутренние элементы системы?

Другие рекомендуют протоколировать его в файл журнала вне корня документа.

Есть ли у вас какие-либо возражения по этому поводу?

Некоторые используют обработку ошибок для регистрации в таблице SQL.

Разве вы не думаете, что это противоречивая идея – регистрировать ошибки базы данных в базе данных?

Какова наилучшая практика для обработки ошибок в PHP?

Вы уже показали это: покажите в dev и войдите в prod. Все контролируется по всему сайту через несколько простых вариантов конфигурации.

Какова наилучшая практика для обработки ошибок в блоке catch?

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

Таким образом, ваш код должен быть

 <?php // Error handling error_reporting(-1); ini_set('display_errors',0); ini_set('log_errors',1); // Get credentials from outside document root require_once('../settings.php'); // Tests connection to database $dbh = new PDO( sprintf( 'mysql:host=%s;dbname=%s;port=%s;charset=%s', $settings['host'], $settings['name'], $settings['port'], $settings['charset'] ), $settings['username'], $settings['password'] ); // Prevents emulated prepares and activates error handling // PDO::ERRMODE_EXCEPTION $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

Теперь на вопрос, который вы озвучили в комментарии.

Пользовательский экран ошибок – это совсем другое дело, и ваш код особенно неприятен. Ни он, ни ошибка 404, ни перенаправление HTTP не должны использоваться (это очень плохо для SEO).

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

При столкновении с фатальной ошибкой (и неперехваченное исключение – одно) PHP отвечает не с статусом HTTP 200 OK, а с состоянием 5xx. И каждый веб-сервер может перехватить этот статус и показать страницу с соответствующей ошибкой. Например, для Apache это было бы

 ErrorDocument 503 server_error.html 

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

Или вы можете настроить собственный обработчик ошибок в PHP, который будет обрабатывать все ошибки PHP, пример можно увидеть в статье, которую я написал по этому вопросу: (im) правильное использование try..catch.