error_get_last()
Функция error_get_last() в PHP возвращает информацию о последней ошибке: тип, сообщение, файл и строку.
Обработка ошибок — важная часть программирования на PHP, поскольку ошибки могут возникнуть в любой момент выполнения скрипта. Функция error_get_last() — это встроенная функция PHP, которая позволяет получить информацию о последней записанной ошибке: её тип, сообщение, файл и строку. Это даёт возможность логировать ошибку или реагировать на неё в коде. В этой главе объясняется, что возвращает функция, когда она возвращает null, какие ошибки она фиксирует, а какие нет, и как правильно использовать её в современном PHP.
Что возвращает error_get_last()
error_get_last() не принимает аргументов и возвращает информацию о последней ошибке, которую PHP зафиксировал в рамках текущего запроса. Возможны два варианта возвращаемого значения:
- Ассоциативный array с четырьмя ключами, если ошибка произошла.
null, если ни одна ошибка ещё не была записана.
Array имеет следующую структуру:
[
'type' => 2, // int: the error level (E_WARNING here)
'message' => 'fopen(...): ...', // string: the error description
'file' => '/path/to/script.php', // string: file where the error happened
'line' => 12, // int: line number where it happened
]Элемент type — целое число, соответствующее одной из констант уровня ошибок PHP: например, E_WARNING (2), E_NOTICE (8), E_USER_WARNING (512) или E_DEPRECATED. Полный список см. в справочнике ошибок PHP.
Что фиксирует функция, а что нет
Именно здесь многие допускают ошибку, поэтому стоит быть точнее:
- Функция фиксирует сообщённые ошибки, предупреждения, уведомления и устаревания — всё, что проходит через стандартный механизм ошибок PHP, включая вызванные с помощью
trigger_error(). - Функция не фиксирует исключения. В современном PHP (7.0+) многие сбои выбрасывают исключения вместо вызова ошибок — например, деление и взятие остатка по нулю выбрасывают
DivisionByZeroError, а не предупреждение. Такие ситуации необходимо обрабатывать с помощьюtry/catch, иerror_get_last()их не увидит. - Функция видит только те ошибки, которые фактически сообщены. Если уровень ошибки отфильтрован функцией
error_reporting(), она не будет зафиксирована. При отладке включайтеerror_reporting(E_ALL), чтобы ничего не пропускалось молча.
По этой причине error_get_last() наиболее полезна сразу после вызова встроенной функции, которая сигнализирует о сбое через предупреждение (например, fopen(), file_get_contents() или unlink()), а также внутри пользовательской функции завершения для перехвата фатальной ошибки, прервавшей запрос.
Примеры
Чтение последнего предупреждения после неудачного вызова fopen()
Такие функции, как fopen(), возвращают false и вызывают E_WARNING при сбое. Оператор @ подавляет вывод предупреждения, при этом error_get_last() всё равно может его прочитать:
<?php
error_reporting(E_ALL);
$handle = @fopen("/no/such/file.txt", "r");
if ($handle === false) {
$error = error_get_last();
echo "Type: " . $error['type'] . "\n";
echo "Message: " . $error['message'] . "\n";
echo "Line: " . $error['line'] . "\n";
}
?>Вывод:
Type: 2
Message: fopen(/no/such/file.txt): Failed to open stream: No such file or directory
Line: 4Значение type равно 2 — это значение константы E_WARNING, а сообщение получено напрямую от fopen().
Перехват ошибки, вызванной вручную
Вы можете записать собственную ошибку с помощью trigger_error() и затем прочитать её:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '0');
trigger_error("Invalid configuration value", E_USER_WARNING);
$error = error_get_last();
echo "Message: " . $error['message'] . "\n";
echo "Type: " . $error['type'] . "\n"; // 512 = E_USER_WARNING
?>Вывод:
Message: Invalid configuration value
Type: 512Когда ошибок не было
Если ничего не пошло не так, функция возвращает null — поэтому всегда проверяйте результат перед обращением к ключам array:
<?php
$error = error_get_last();
var_dump($error); // NULL — guard against this before using $error['message']
?>Вывод:
NULLТипичные ошибки
- Всегда проверяйте результат на null (
if ($error !== null)) перед обращением к$error['message'], иначе вы вызовете новое предупреждение «trying to access array offset on null». - Деление на ноль больше не является предупреждением. Используйте
try/catchдляDivisionByZeroError;error_get_last()не сообщит о нём. - Для программного логирования, а не просто проверки, рассмотрите возможность использования
error_log()или пользовательского обработчика, зарегистрированного черезset_error_handler().
Заключение
error_get_last() возвращает тип, сообщение, файл и строку последней ошибки, записанной PHP, или null, если ошибок не было. Используйте её сразу после встроенной функции, завершившейся с предупреждением, или внутри функции завершения — и помните, что исключения (включая современное деление на ноль) требуют try/catch.