W3docs

Ошибки PHP

Узнайте об уровнях ошибок PHP, константах E_*, разнице между ошибками и исключениями, настройке отчётов и лучших практиках обработки ошибок.

Встреча с ошибками — это нормальная часть написания кода на PHP. Чем быстрее вы научитесь читать ошибку, понимать её уровень, причину и способ реакции, тем быстрее вы будете выпускать рабочий код. На этой странице объясняются уровни ошибок PHP (константы E_*), разница между ошибками и исключениями в современном PHP, а также практический подход к отчётности, логированию и обработке ошибок.

Уровни ошибок PHP

Когда PHP обнаруживает проблему, он сигнализирует о ней на определённом уровне, идентифицируемом константой E_*. Уровень говорит о серьёзности проблемы и о том, продолжит ли скрипт выполнение. Эти константы комбинируются с error_reporting() и директивой error_reporting в php.ini, чтобы определить, какие уровни отображаются или логируются.

КонстантаОстанавливает скрипт?Значение
E_ERRORДаФатальная ошибка во время выполнения, например вызов неопределённой функции.
E_WARNINGНетПредупреждение во время выполнения, например include отсутствующего файла.
E_PARSEДаСинтаксическая ошибка во время компиляции; файл так и не запускается.
E_NOTICEНетНезначительная проблема, например чтение неопределённой переменной.
E_DEPRECATEDНетФункция ещё работает, но будет удалена в будущей версии.
E_USER_ERROR / E_USER_WARNING / E_USER_NOTICEЗависитУровни, которые вы сами генерируете с помощью trigger_error().
E_STRICTНетРекомендации для совместимого с будущими версиями кода (включены в E_ALL начиная с PHP 7).
E_ALLБитовая маска, включающая все уровни — используйте это при разработке.

Это битовые константы, поэтому их можно комбинировать оператором побитового ИЛИ (|) и исключать уровни с помощью & и ~:

<?php
// Report everything except notices and deprecations
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);

Важно: Начиная с PHP 8.0, многие бывшие предупреждения и уведомления были повышены до бросаемых исключений Error (например, чтение неопределённого ключа массива теперь вызывает предупреждение, а вызов неопределённого метода бросает Error). Важно понимать, является ли проблема поднятой ошибкой или брошенным исключением — это определяет способ её перехвата (см. ниже).

Ошибки и исключения

В PHP есть два связанных, но раздельных механизма:

  • Традиционные ошибки поднимаются движком и маршрутизируются через error_reporting, display_errors и необязательный обработчик, установленный с помощью set_error_handler(). Это не объекты, которые можно перехватить через catch (если только ваш обработчик не преобразует их).
  • Исключения — это объекты, которые вы throw-аете и перехватываете с помощью блоков try/catch. Начиная с PHP 7, фатальные ошибки движка тоже бросаются как объекты Error (например, TypeError или DivisionByZeroError), и оба — Exception и Error — реализуют интерфейс Throwable, поэтому catch (\Throwable $e) перехватывает всё, что можно поймать.
<?php
try {
    // intdiv() throws a DivisionByZeroError on division by zero
    echo intdiv(10, 0);
} catch (\Throwable $e) {
    echo get_class($e) . ": " . $e->getMessage();
}
// Output: DivisionByZeroError: Division by zero

Распространённые причины ошибок PHP

Большинство ошибок восходит к небольшому набору причин:

  • Синтаксические ошибки — пропущенная точка с запятой или несовпадающая скобка (E_PARSE).
  • Неопределённые символы — использование переменной, константы, функции или ключа массива, которые не существуют.
  • Несовпадение типов — передача значения неправильного типа в типизированный параметр (бросает TypeError).
  • Устаревшие возможности — функции или синтаксис, намеченные к удалению (E_DEPRECATED).
  • Ограничения ресурсов — исчерпание memory_limit или превышение max_execution_time.
  • Внешние сбои — отсутствующий файл или отказ соединения с базой данных/API либо истечение его времени ожидания.
  • Неперехваченные исключенияthrow без соответствующего catch, что превращается в фатальную ошибку.
<?php
// Reading an undefined variable raises an E_WARNING and yields null
echo $undefined_variable ?? "fallback";
// Output: fallback

Оператор объединения с null (??) в примере выше — это идиоматический способ прочитать значение, которое может быть неопределённым, без вызова предупреждения.

Настройка отчётности об ошибках

Управляйте тем, какие уровни отображаются и куда они направляются. При разработке показывайте всё; в продакшене скрывайте ошибки от пользователей, но логируйте их.

<?php
// Development: show all errors on screen
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Production: hide from users, write to the error log instead
// error_reporting(E_ALL);
// ini_set('display_errors', '0');
// ini_set('log_errors', '1');

Эквивалентные настройки в php.ini: error_reporting, display_errors, log_errors и error_log. Для программного управления смотрите error_reporting(), а для получения последней ошибки используйте error_get_last().

Обработка ошибок в коде

Существуют три взаимодополняющих инструмента:

1. Перехватывайте исключения с помощью try/catch, чтобы восстановимый сбой не завершал скрипт:

<?php
function safeDivide(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException("Cannot divide by zero");
    }
    return $a / $b;
}

try {
    echo safeDivide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Handled: " . $e->getMessage();
}
// Output: Handled: Cannot divide by zero

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

<?php
set_error_handler(function (int $level, string $message, string $file, int $line) {
    // Turn a traditional warning/notice into an ErrorException so it can be caught
    throw new ErrorException($message, 0, $level, $file, $line);
});

try {
    // Reading a missing file raises an E_WARNING, now converted to an exception
    $contents = file_get_contents('/no/such/file.txt');
} catch (\Throwable $e) {
    echo "Caught: " . $e->getMessage();
}
// Output: Caught: file_get_contents(/no/such/file.txt): Failed to open stream: No such file or directory

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

Лучшие практики

  • Устанавливайте display_errors в 0 в продакшене — утечка трассировок стека является угрозой безопасности. Вместо этого используйте log_errors с настроенным error_log.
  • При разработке используйте error_reporting(E_ALL), чтобы уведомления и предупреждения об устаревших функциях проявлялись как можно раньше.
  • Предпочитайте catch (\Throwable $e) на верхнем уровне для перехвата и Exception, и Error.
  • Никогда не заглушайте проблемы оператором @; устраняйте причину или обрабатывайте её явно.
  • Централизуйте логирование с помощью error_log(), чтобы все сбои попадали в одно место.

Заключение

Чтение ошибки PHP начинается с определения её уровня и того, является ли она поднятой ошибкой или брошенным исключением. С error_reporting(), настроенным для каждой среды, пользовательским обработчиком, направляющим ошибки в систему исключений, и try/catch вокруг потенциально проблемного кода, вы сможете быстро диагностировать проблемы и обеспечить устойчивость продакшена. Продолжайте с PHP Exceptions и error_reporting() для более глубокого изучения.

Практика

Практика
Какие типы ошибок в PHP упоминаются в статье?
Какие типы ошибок в PHP упоминаются в статье?
Was this page helpful?