Иногда ваше приложение не запускается должным образом, что приводит к ошибкам. Есть ряд причин, которые могут вызвать ошибки, например:
- Веб-серверу может не хватить места на диске;
- Пользователь мог ввести недопустимое значение в поле формы;
- Файл или запись базы данных, к которой вы пытались получить доступ, возможно, не существует;
- Приложение может не иметь разрешения на запись в файл на диске;
- Служба, к которой приложение должно получить доступ, может быть временно недоступна.
Эти типы ошибок известны как ошибки времени выполнения, потому что они возникают во время выполнения скрипта. Они отличаются от синтаксических ошибок, которые необходимо исправлять перед запуском скриптов.
Профессиональное приложение должно иметь возможность изящно обрабатывать такие ошибки времени выполнения. Обычно это означает более четкое и точное информирование пользователя о проблеме.
Понимание уровней ошибок
Обычно, когда возникает проблема, препятствующая правильной работе скрипта, механизм PHP выдает ошибку. Каждая ошибка представлена целым числом и соответствующей константой. В следующей таблице перечислены некоторые из распространенных уровней ошибок:
Название | Значение | Описание |
---|---|---|
E_ERROR |
1 |
Неустранимая ошибка времени выполнения от которой невозможно избавиться. Выполнение скрипта немедленно прекращается. |
E_WARNING |
2 |
Предупреждение во время выполнения. Она несущественна, и большинство ошибок попадают в эту категорию. Выполнение скрипта не останавливается. |
E_NOTICE |
8 |
Уведомление во время выполнения. Указывает, что скрипт обнаружил что-то, что могло быть ошибкой, хотя такая ситуация также может возникнуть при обычном запуске скрипта. |
E_USER_ERROR |
256 |
Сообщение о фатальной пользовательской ошибке. Она похожа на E_ERROR , за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_USER_WARNING |
512 |
Предупреждающее сообщение, созданное пользователем без фатального исхода. Она похожа на E_WARNING , за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_USER_NOTICE |
1024 |
Сообщение с уведомлением, созданное пользователем. Она похожа на E_NOTICE за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_STRICT |
2048 |
Не совсем ошибка, но срабатывает всякий раз, когда PHP встречает код, который может привести к проблемам или несовместимости пересылки. |
E_ALL |
8191 |
Все ошибки и предупреждения, кроме E_STRICT до PHP 5.4.0. |
Дополнительные сведения об уровнях ошибок см. в справочнике по уровням ошибок PHP.
Механизм PHP вызывает ошибку всякий раз, когда он сталкивается с проблемой в вашем скрипте, но вы также можете инициировать ошибки самостоятельно, чтобы генерировать более удобные сообщения об ошибках. Таким образом вы можете сделать свое приложение более сложным. В следующем разделе описаны некоторые из распространенных методов, используемых для обработки ошибок в PHP:
Базовая обработка ошибок с помощью функции die()
Рассмотрим следующий пример, в котором просто попытаемся открыть текстовый файл только для чтения.
<?php
// Пробуем открыть несуществующий файл
$file = fopen("sample.txt", "r"); // Выводит: Warning: fopen(sample.txt) [function.fopen]: failed to open stream: No such file or directory in C:wampwwwprojecttest.php on line 2
?>
Если мы выполним несколько простых шагов, мы сможем предотвратить получение пользователями такого сообщения об ошибке.
<?php
if(file_exists("sample.txt")){
$file = fopen("sample.txt", "r");
} else{
die("Error: The file you are trying to access doesn't exist.");
}
?>
Как вы можете видеть, реализовав простую проверку, существует ли файл перед попыткой доступа к нему, мы можем сгенерировать сообщение об ошибке, которое будет более понятным для пользователя.
Используемая выше функция die()
просто отображает пользовательское сообщение об ошибке и завершает текущий скрипт, если файл sample.txt
не найден.
Создание собственного обработчика ошибок
Вы можете создать свою собственную функцию обработчика ошибок, чтобы справляться с ошибкой времени выполнения, генерируемой механизмом PHP. Пользовательский обработчик ошибок обеспечивает большую гибкость и лучший контроль над ошибками; он может проверять ошибку и решать, что с ней делать — отображать сообщение пользователю, регистрировать ошибку в файле или базе данных или отправлять по электронной почте, попытаться исправить проблему и продолжить, выйти из выполнения скрипта или вообще игнорировать ошибку.
Функция пользовательского обработчика ошибок должна иметь возможность обрабатывать как минимум два параметра (errno и errstr), однако она может дополнительно принимать три дополнительных параметра (errfile, errline и errcontext), как описано ниже:
Параметр | Описание |
---|---|
Обязательно — следующие параметры обязательны | |
errno. | Задает уровень ошибки в виде целого числа. Это соответствует соответствующей константе уровня ошибки (E_ERROR , E_WARNING и т. д.). |
errstr. | Задает сообщение об ошибке в виде строки. |
Опционально — следующие параметры являются необязательными | |
errfile. | Задает имя файла скрипта, в котором произошла ошибка. |
errline. | Задает номер строки, в которой произошла ошибка. |
errcontext. | Задает массив, содержащий все переменные и их значения, которые существовали на момент возникновения ошибки. Полезно для отладки. |
Вот пример простой пользовательской функции обработки ошибок. Этот обработчик customError()
запускается всякий раз, когда возникает ошибка, какой бы тривиальной она ни была. Затем он выводит сведения об ошибке в браузер и останавливает выполнение скрипта.
<?php
// Функция обработчика ошибок
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
?>
Вам нужно указать PHP, чтобы он использовал вашу пользовательскую функцию обработчика ошибок — просто вызовите встроенную функцию set_error_handler()
, передав имя функции.
<?php
// Функция обработчика ошибок
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
// Устанавливаем обработчик ошибок
set_error_handler("customError");
// Вызываем ошибку
echo($test);
?>
Регистрация ошибок
Журнал сообщений об ошибках в текстовом файле
Вы также можете записать подробную информацию об ошибке в файл журнала, например:
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - ");
$message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
$message .= "Variables:" . print_r($errcontext, true) . "rn";
error_log($message, 3, "logs/app_errors.log");
die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>
Отправка сообщений об ошибках по электронной почте
Вы также можете отправить электронное письмо с подробностями об ошибке, используя ту же функцию error_log()
.
<?php
function calcDivision($dividend, $divisor){
if ($divisor == 0){
trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - ");
$message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
$message .= "Variables:" . print_r($errcontext, true) . "rn";
error_log($message, 1, "webmaster@example.com");
die("There was a problem, please try again. Error report submitted to webmaster.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>
Вызов ошибок
Хотя движок PHP выдает ошибку всякий раз, когда он сталкивается с проблемой в вашем скрипте, вы также можете вызвать ошибки самостоятельно. Это может помочь сделать ваше приложение более надежным, поскольку оно может выявлять потенциальные проблемы до того, как они перерастут в серьезные ошибки.
Чтобы вызвать ошибку в скрипте, вызовите функцию trigger_error()
, передав сообщение об ошибке, которое вы хотите сгенерировать:
trigger_error("There was a problem.");
Рассмотрим следующую функцию, которая вычисляет деление двух чисел.
<?php
function calcDivision($dividend, $divisor){
return($dividend / $divisor);
}
// Вызываем функцию
echo calcDivision(10, 0); // Выводит: Warning: Division by zero in C:wampwwwprojecttest.php on line 3
?>
Это сообщение выглядит не очень информативным. Рассмотрим следующий пример, в котором для генерации ошибки используется функция trigger_error()
.
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("Делитель не может быть нулевым", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
// Вызываем функцию
echo calcDivision(10, 0); // Выводит: Warning: Делитель не может быть нулевым C:wampwwwprojecterror.php on line 4
?>
Как видите, сообщение об ошибке, созданное во втором примере, более четко объясняет проблему по сравнению с предыдущим.
PHP5 Обработка ошибок
Обработка ошибок по умолчанию в PHP очень проста. Сообщение об ошибке с именем файла, строка число и сообщение, описывающее ошибку, отправляется в браузер.
При создании скриптов и веб-приложений, обработка ошибок, является важной
частью. Если коду не хватает кода проверки ошибок, программа может выглядеть
непрофессионально и Вы можете быть открыты для рисков безопасности.
Учебник содержит несколько из наиболее распространенных методов проверки ошибок в PHP.
Вы узнаете различные методы обработки ошибок:
- Простое заявление
это()
- Пользовательские ошибки и триггеры ошибок
- Отчеты об ошибках
PHP Основная обработка ошибок
В первом примере показан простой скрипт, открывающий текстовый файл: использование функции это()
Пример
<?php
$file=fopen(«welcome.txt»,»r»);
?>
Если файл не существует, Вы можете получить ошибку, как эта:
Внимание: fopen(welcome.txt) [function.fopen]: не удалось открыть поток:
Нет такого файла или каталога в C:webfoldertest.php на линии 2
Чтобы запретить пользователю получать сообщение об ошибке, подобное приведенному примеру выше, мы проверяем
файл, существует ли он до того, как мы попытаемся получить к нему доступ:
Пример
<?php
if(!file_exists(«welcome.txt»)) {
die(«Файл не найден»);
}
else {
$file=fopen(«welcome.txt»,»r»);
}
?>
Теперь, если файл не существует вы получите ошибку, как эта:
Файл не найден
Приведенный ниже код более эффективен, чем предыдущий код, поскольку он использует простой механизм обработки ошибок для остановки сценария после ошибки.
Тем не менее, остановить просто сценарий не всегда правильный путь. Рассмотрим альтернативные функции PHP для обработки ошибок.
PHP Создание пользовательского обработчика ошибок
Создать пользовательский обработчик ошибок довольно просто. Создаем специальную функцию, которая может быть вызвана при возникновении ошибки в PHP.
Эта функция должна быть способна обрабатывать, как минимум два параметра (уровень ошибки и сообщение об ошибке),
но можно принимать до пяти параметров (дополнительно: файл, номер строки и контекст ошибки):
Синтаксис
error_function(error_level,error_message,
error_file,error_line,error_context)
Параметр | Описание |
---|---|
error_level | Необходимо. Указывает уровень отчета об ошибках для пользовательской ошибки. Должно быть числовое значение. См. таблицу ниже для возможных уровней отчета об ошибках |
error_message | Необходимо. Указывает сообщение об ошибке определяемая пользователем |
error_file | Необязательно. Задает имя файла, в котором произошла ошибка |
error_line | Необязательно. Указывает номер строки, в которой произошла ошибка |
error_context | Необязательно. Задает массив, содержащий все переменные и их значения, используемые при возникновении ошибки |
PHP Уровни отчетов об ошибках
Эти уровни отчетов об ошибках, являются различными типами ошибок, для которых может использоваться определяемый пользователем обработчик ошибок:
Значение | Констант | Описание |
---|---|---|
2 | E_WARNING | Неустранимые ошибки выполнения. Выполнение скрипта не останавливается |
8 | E_NOTICE | Уведомления среды выполнения. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария, как обычно |
256 | E_USER_ERROR | Неустранимая ошибка пользователя. Это похоже на набор E_ERROR установленный программистом с помощью функции PHP trigger_error() |
512 | E_USER_WARNING | Неустранимое пользовательское предупреждение. Это похоже на набор E_WARNING установленный программистом с помощью функции PHP trigger_error() |
1024 | E_USER_NOTICE | Автоматическое уведомление пользователя. Это похоже на набор E_NOTICE устанавливается программистом с помощью функции PHP trigger_error() |
4096 | E_RECOVERABLE_ERROR | Перехватываемая неустранимая ошибка. Это похоже на набор E_ERROR но может быть перехватана пользователем, определенной обработкой (смотреть также set_error_handler()) |
8191 | E_ALL | Все ошибки и предупреждение (E_STRICT становится частью E_ALL в PHP 5.4) |
Теперь давайте создадим функцию для обработки ошибок:
Пример
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Конечный Script»;
die();
}
Приведенный выше код, является простой функцией обработки ошибок. Когда он срабатывает, он получает код ошибки и сообщение об ошибке.
Затем выводится уровень ошибки и сообщение и завершается сценарий.
Теперь, когда Вы создали функцию обработки ошибок, Вы должны решить, когда она должно сработать.
PHP Установить обработчик ошибок
Обработчик ошибок по умолчанию для PHP является встроенным обработчиком ошибок.
Мы собираемся сделать функцию над обработчиком ошибок по умолчанию на время скрипта.
Можно изменить обработчик ошибок для применения только к некоторым ошибкам, таким образом,
сценарий может обрабатывать различные ошибки по-разному.
Однако, в этом примере мы будем использовать наш пользовательский обработчик ошибок для всех ошибок:
set_error_handler(«customError»);
Поскольку мы хотим, чтобы наша пользовательская функция обрабатывала все ошибки, set_error_handler()
требуется только один параметр, второй параметр может быть добавлен, чтобы указать уровень ошибки.
Тестирование обработчика ошибок при попытке вывести несуществующую переменную:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr»;
}
//установить обработчик ошибок
set_error_handler(«customError»);
//Вызов ошибки
echo($test);
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [8] Неопределенна переменная: test
PHP Вызвать ошибку
В скрипте, где пользователи могут вводить данные, полезно инициировать ошибки, когда происходит незаконный ввод.
В PHP это делается с помощью функции trigger_error()
.
В этом примере возникает ошибка, если $test
переменная больше, чем 1
:
Пример
<?php
$test=2;
if ($test>=1)
{
trigger_error(«Значение должно быть 1 или ниже»);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Заметьте: Значение должно быть 1 или ниже
в C:webfoldertest.php на линии 6
Ошибка может быть вызвана в любом месте сценария и путем добавления
второй параметр, Вы можете указать, какой уровень ошибки срабатывает.
Возможные типы ошибок:
- E_USER_ERROR — Неустранимая пользовательская ошибка выполнения. Ошибки, из которых невозможно восстановить. Выполнение скрипта прекращается
- E_USER_WARNING — Непоправимое пользовательское предупреждение во время выполнения. Выполнение скрипта не останавливается
- E_USER_NOTICE — Невыполнение. Уведомление о времени выполнения, созданное пользователем. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария
В этом примере E_USER_WARNING происходит, если переменная $test
больше, чем 1
. Если происходит E_USER_WARNING мы будем использовать наш пользовательский обработчик ошибок и закончить сценарий:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Закончить Script»;
die();
}
//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);
//вызов ошибки
$test=2;
if ($test>=1) {
trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [512] Значение должно быть 1 или ниже
Конец скрипта
Теперь, когда мы научились создавать собственные ошибки и как их вызвать,
давайте посмотрим на ошибки.
PHP Регистрация ошибок
По умолчанию, PHP отправляет отчет об ошибке в систему регистрации на сервер или файл,
в зависимости от того, как конфигурация error_log установлена в php.ini-файл. По
с помощью функции error_log()
можно отправлять журнал ошибок в указанный файл или в удаленное место назначения.
Отправка сообщений об ошибках по электронной почте, может быть хорошим способом получения уведомления о конкретных ошибках.
PHP Отправка сообщение об ошибке по электронной почте
В приведенном ниже примере мы отправим электронное письмо с сообщением об ошибке и
сценарий, если возникает ошибка:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Веб-мастер был уведомлен»;
error_log(«Ошибка: [$errno] $errstr»,1,
«someone@example.com»,»От: webmaster@example.com»);
}
//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);
//вызов ошибки
$test=2;
if ($test>=1) {
trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [512] Значение должно быть 1 или ниже
Веб-мастер был уведомлен
И почта, полученная из кода выше, выглядит так:
Ошибка: [512] начение должно быть 1 или ниже
Не должно использоваться со всеми ошибками. Регулярные ошибки должны быть зарегистрированы на
сервере, использующий систему регистрации PHP по умолчанию.
Обработка ошибок по умолчанию в PHP очень просто. Сообщение об ошибке с именем файла, номер строки и сообщение с описанием ошибки отправляется в браузер.
PHP Обработка ошибок
При создании сценариев и веб-приложений, обработка ошибок является важной частью. Если код отсутствует код ошибки проверки, ваша программа может выглядеть очень непрофессионально, и вы можете быть открытыми для угроз безопасности.
Это руководство содержит некоторые из наиболее распространенных ошибок методов в PHP проверки.
Мы покажем различные методы обработки ошибок:
- Простой » die() « заявление
- Пользовательские ошибки и триггеры ошибок
- Отчет об ошибках
Основная обработка ошибок: Использование die() функция
Первый пример показывает простой скрипт, который открывает текстовый файл:
<?php
$file=fopen(«welcome.txt»,»r»);
?>
Если файл не существует, вы можете получить сообщение об ошибке, подобное следующему:
Warning : fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in C:webfoldertest.php on line 2
Чтобы запретить пользователю получать сообщение об ошибке, как показано выше, мы проверяем, существует ли файл, прежде чем мы пытаемся получить к нему доступ:
<?php
if(!file_exists(«welcome.txt»)) {
die(«File not found»);
}
else {
$file=fopen(«welcome.txt»,»r»);
}
?>
Теперь, если файл не существует, вы получите сообщение об ошибке, как это:
Код выше является более эффективным, чем ранее кода, так как он использует простой механизм обработки ошибок, чтобы остановить скрипт после ошибки.
Однако, просто остановить скрипт не всегда правильный путь. Давайте посмотрим на альтернативные функции PHP для обработки ошибок.
Создание пользовательского обработчика ошибок
Создание обработчика ошибок довольно просто. Мы просто создаем специальную функцию, которая может быть вызвана, когда возникает ошибка в PHP.
Эта функция должна быть в состоянии обрабатывать как минимум два параметров (уровень ошибок и сообщение об ошибке) , но может принимать до пяти параметров (optionally: file, line-number, and the error context) :
Синтаксис
error_function(error_level,error_message,
error_file,error_line,error_context)
параметр | Описание |
---|---|
error_level | Необходимые. Определяет уровень отчета об ошибках для определенного пользователя ошибки. Должно быть числовое значение. Смотрите таблицу ниже для возможных уровней отчета об ошибке |
error_message | Необходимые. Определяет сообщение об ошибке для определенного пользователя ошибки |
error_file | Необязательный. Задает имя файла, в котором произошла ошибка |
error_line | Необязательный. Задает номер строки, в которой произошла ошибка |
error_context | Необязательный. Определяет массив, содержащий каждую переменную, и их значения, используется, когда произошла ошибка |
Ошибка уровней отчетов
Эти уровни отчета об ошибке различных типов ошибок определенного пользователя обработчик ошибок может быть использован для:
Стоимость | постоянная | Описание |
---|---|---|
2 | E_WARNING | Нефатальные ошибки во время выполнения. Выполнение скрипта не остановлено |
8 | E_NOTICE | Время выполнения уведомление. Сценарий нашел что-то, что может быть ошибкой, но может также произойти при выполнении сценария нормально |
256 | E_USER_ERROR | Фатальные пользователи ошибка. Это как E_ERROR установленный программистом с помощью функции PHP trigger_error() |
512 | E_USER_WARNING | Некритические пользователи предупреждение. Это как E_WARNING установленный программистом с помощью функции PHP trigger_error() |
1024 | E_USER_NOTICE | Пользователь сгенерированные уведомления. Это как E_NOTICE установленный программистом с помощью функции PHP trigger_error() |
4096 | E_RECOVERABLE_ERROR | Catchable фатальная ошибка. Это как E_ERROR , но может быть перехвачено определенным пользователем ручки (see also set_error_handler() ) |
8191 | E_ALL | Все ошибки и предупреждения (E_STRICT became a part of E_ALL in PHP 5.4) |
Теперь давайте создадим функцию для обработки ошибок:
function customError($errno, $errstr) {
echo «<b>Error:</b> [$errno] $errstr<br>»;
echo «Ending Script»;
die();
}
Код выше простая функция обработки ошибок. При срабатывании, он получает уровень ошибки и сообщение об ошибке. Затем он выводит уровень ошибки и сообщение и завершает сценарий.
Теперь, когда мы создали функцию обработки ошибок, мы должны решить, когда он должен быть запущен.
Установить обработчик ошибок
Обработчик ошибок по умолчанию для PHP является встроенным в обработчик ошибок. Мы собираемся сделать функцию выше обработчика ошибок по умолчанию для длительности сценария.
Можно изменить обработчик ошибок для применения только для некоторых ошибок, таким образом скрипт может обрабатывать различные ошибки по-разному. Однако, в этом примере мы будем использовать наш обработчик ошибок для всех ошибок:
set_error_handler(«customError»);
Так как мы хотим , чтобы наша пользовательская функция , чтобы обработать все ошибки, то set_error_handler() нужен только один параметр, второй параметр может быть добавлен , чтобы указать уровень ошибки.
пример
Тестирование обработчика ошибок, пытаясь выходным переменным, которая не существует:
<?php
//error handler function
function customError($errno, $errstr) {
echo «<b>Error:</b> [$errno] $errstr»;
}
//set error handler
set_error_handler(«customError»);
//trigger error
echo($test);
?>
Выход выше код должен быть что-то вроде этого:
Error: [8] Undefined variable: test
Trigger ошибки
В сценарии, где пользователи могут вводить данные полезно вызвать ошибки при возникновении недопустимого ввода. В PHP это делается с помощью trigger_error() функции.
пример
В этом примере ошибка возникает , если «test» переменная больше , чем «1» :
<?php
$test=2;
if ($test>=1)
{
trigger_error(«Value must be 1 or below»);
}
?>
Выход выше код должен быть что-то вроде этого:
Notice : Value must be 1 or below
in C:webfoldertest.php on line 6
Ошибка может быть вызвана в любом месте вы хотите в сценарии, и путем добавления второго параметра вы можете указать, что срабатывает уровень ошибки.
Возможные типы ошибок:
- E_USER_ERROR — Fatal пользователей ошибка времени выполнения. Ошибки, которые не могут быть восстановлены из. Выполнение скрипта останавливается
- E_USER_WARNING — Некритические пользователи предупреждения во время выполнения. Выполнение скрипта не остановлено
- E_USER_NOTICE — по умолчанию. Пользователь генерируемого во время выполнения уведомления. Сценарий нашел что-то, что может быть ошибкой, но может также произойти при выполнении сценария нормально
пример
В этом примере E_USER_WARNING происходит , если «test» переменная больше , чем «1» . При возникновении E_USER_WARNING мы будем использовать наш обработчик ошибок и закончить сценарий:
<?php
//error handler function
function customError($errno, $errstr) {
echo «<b>Error:</b> [$errno] $errstr<br>»;
echo «Ending Script»;
die();
}
//set error handler
set_error_handler(«customError»,E_USER_WARNING);
//trigger error
$test=2;
if ($test>=1) {
trigger_error(«Value must be 1 or below»,E_USER_WARNING);
}
?>
Выход выше код должен быть что-то вроде этого:
Error: [512] Value must be 1 or below
Ending Script
Теперь, когда мы научились создавать свои собственные ошибки и как вызвать их, давайте посмотрим на ведение журнала ошибок.
Ведение журнала ошибок
По умолчанию, PHP отправляет журнал ошибок в системе регистрации сервера или файла, в зависимости от того, как конфигурация error_log установлен в файле php.ini. При использовании error_log() функции вы можете отправить журналы ошибок в указанный файл или удаленный пункт назначения.
Отправка сообщения об ошибках в себя по электронной почте может быть хорошим способом получать уведомления о конкретных ошибках.
Отправить сообщение об ошибке по E-Mail
В примере ниже мы будем посылать электронную почту с сообщением об ошибке и завершить сценарий, если возникает специфическая ошибка:
<?php
//error handler function
function customError($errno, $errstr) {
echo «<b>Error:</b> [$errno] $errstr<br>»;
echo «Webmaster has been notified»;
error_log(«Error: [$errno] $errstr»,1,
«[email protected]»,»From: [email protected]»);
}
//set error handler
set_error_handler(«customError»,E_USER_WARNING);
//trigger error
$test=2;
if ($test>=1) {
trigger_error(«Value must be 1 or below»,E_USER_WARNING);
}
?>
Выход выше код должен быть что-то вроде этого:
Error: [512] Value must be 1 or below
Webmaster has been notified
И почта, полученная из приведенной выше коды выглядит следующим образом:
Error: [512] Value must be 1 or below
Это не должно использоваться со всеми ошибками. Обычные ошибки должны быть авторизованы на сервере, используя систему по умолчанию протоколирования PHP.
(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP
set_error_handler —
Задаёт пользовательский обработчик ошибок
Описание
set_error_handler(?callable $callback
, int $error_levels
= E_ALL
): ?callable
Функция может быть использована для определения пользовательских обработчиков
ошибок во время выполнения, например, в приложениях, которые должны выполнять
очистку файлов/данных в случае возникновения критической ошибки
или при инициировании ошибки в ответ на определённые условия
(используя функцию trigger_error()).
Важно помнить, что стандартный обработчик ошибок PHP не будет обрабатывать
никакие типы ошибок, определённые в error_levels
,
пока callback-функция не вернёт false
. Пользовательский обработчик будет
вызываться в случае возникновения любой ошибке, независимо от настроек, заданных функцией
error_reporting.
Также обратите внимание, что обработчик обязан при необходимости остановить
выполнение скрипта, вызвав функцию exit().
Если происходит возврат из обработчика ошибок,
управление передаётся следующему выражению, стоящему за тем, что вызвало ошибку.
Ошибки следующих типов не могут быть обработаны пользователем:
E_ERROR
, E_PARSE
,
E_CORE_ERROR
, E_CORE_WARNING
,
E_COMPILE_ERROR
,
E_COMPILE_WARNING
независимо от того, где они были сгенерированы и большинство
ошибок E_STRICT
, произошедших в файле, где вызвана
функция set_error_handler().
Если ошибки возникают до запуска скрипта (например, пока файл загружается),
пользовательский обработчик не будет вызываться, если на этот момент он
ещё не зарегистрирован.
Список параметров
-
callback
-
Если передано значение
null
, обработчик сбрасывается в состояние по умолчанию.
В противном случае обработчик представляет собой callback-функцию со следующей сигнатурой:handler(
int$errno
,
string$errstr
,
string$errfile
= ?,
int$errline
= ?,
array$errcontext
= ?
): bool-
errno
-
В первый аргументerrno
будет передан уровень
ошибки в виде целого числа.
-
errstr
-
Во второй аргументerrstr
будет передано сообщение
об ошибке в виде строки.
-
errfile
-
Если функция обратного вызова принимает третий параметр
errfile
, то в него будет передано
имя файла, в котором произошла ошибка, в виде строки.
-
errline
-
Если функция обратного вызова принимает четвёртый параметр
errline
, то в него будет передан
номер строки, в которой произошла ошибка, в виде целого
числа.
-
errcontext
-
Если функция обратного вызова принимает пятый параметр
errcontext
, то в него будет передан
массив указателей на активную таблицу символов в точке, где
произошла ошибка. Другими словами,errcontext
будет содержать массив всех переменных, существующих в области
видимости, где произошла ошибка. Пользовательские обработчики ошибок не
должны изменять этот контекст.
Внимание
Этот параметр объявлен УСТАРЕВШИМ начиная с PHP 7.2.0 и
был УДАЛЁН в PHP 8.0.0. Если в вашей функции этот
параметр используется и для него не задано значение по умолчанию, то при
вызове функции обработчика будет выдана ошибка «too few arguments».
Если функция возвращает
false
, управление передаётся встроенному
обработчику ошибок. -
-
error_levels
-
Может использоваться для задания маски, в соответствии с которой будет
вызыватьсяcallback
, по аналогии с
ini-настройкой error_reporting,
которая отвечает за то, какие ошибки будут показаны в отчёте. Без этой
маскиcallback
будет вызываться для
обработки всех происходящих ошибок, вне зависимости от настроек в
error_reporting.
Возвращаемые значения
Возвращает ранее определённый обработчик ошибок (если есть) Если на данный момент используется встроенный обработчик, функция
вернёт null
. Если предыдущий определённый обработчик является методом класса, функция вернёт массив,
содержащий имя класса и имя метода.
Список изменений
Версия | Описание |
---|---|
8.0.0 | Параметр errcontext был удалён и больше не передаётся впользовательскую функцию обработки ошибок. |
7.2.0 | Параметр errcontext объявлен устаревшим. Теперь при егоиспользовании будет вызываться ошибка уровня E_DEPRECATED . |
Примеры
Пример #1
Обработка ошибок с помощью функций set_error_handler()
и trigger_error()
Пример ниже демонстрирует обработку внутренних исключений путём
вызова ошибок разных типов и их обработки пользовательской функцией:
<?php
// функция обработки ошибок
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// Этот код ошибки не включён в error_reporting,
// так что пусть обрабатываются стандартным обработчиком ошибок PHP
return false;
}// может потребоваться экранирование $errstr:
$errstr = htmlspecialchars($errstr);
switch (
$errno) {
case E_USER_ERROR:
echo "<b>Пользовательская ОШИБКА</b> [$errno] $errstr<br />n";
echo " Фатальная ошибка в строке $errline файла $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Завершение работы...<br />n";
exit(1);
case
E_USER_WARNING:
echo "<b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [$errno] $errstr<br />n";
break;
case
E_USER_NOTICE:
echo "<b>Пользовательское УВЕДОМЛЕНИЕ</b> [$errno] $errstr<br />n";
break;
default:
echo
"Неизвестная ошибка: [$errno] $errstr<br />n";
break;
}/* Не запускаем внутренний обработчик ошибок PHP */
return true;
}// функция для тестирования обработчика ошибок
function scale_by_log($vect, $scale)
{
if (!is_numeric($scale) || $scale <= 0) {
trigger_error("log(x) для x <= 0 не определён, вы используете: scale = $scale", E_USER_ERROR);
}
if (!
is_array($vect)) {
trigger_error("Некорректный входной вектор, пропущен массив значений", E_USER_WARNING);
return null;
}$temp = array();
foreach($vect as $pos => $value) {
if (!is_numeric($value)) {
trigger_error("Значение на позиции $pos не является числом, будет использован 0 (ноль)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}
return
$temp;
}// переключаемся на пользовательский обработчик
$old_error_handler = set_error_handler("myErrorHandler");// вызовем несколько ошибок, во-первых, определим массив с нечисловым элементом
echo "vector an";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);// теперь создадим ещё один массив
echo "----nvector b - a notice (b = log(PI) * a)n";
/* Значение на позиции $pos не является числом, будет использован 0 (ноль)*/
$b = scale_by_log($a, M_PI);
print_r($b);// проблема, мы передаём строку вместо массива
echo "----nvector c - a warningn";
/* Некорректный входной вектор, пропущен массив значений */
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL
// критическая ошибка, логарифм от неположительного числа не определён
echo "----nvector d - fatal errorn";
/* log(x) для x <= 0 не определён, вы используете: scale = $scale */
$d = scale_by_log($a, -2.5);
var_dump($d); // До сюда не дойдём никогда
?>
Результатом выполнения данного примера
будет что-то подобное:
vector a Array ( [0] => 2 [1] => 3 [2] => foo [3] => 5.5 [4] => 43.3 [5] => 21.11 ) ---- vector b - a notice (b = log(PI) * a) <b>Пользовательское УВЕДОМЛЕНИЕ</b> [1024] Значение на позиции 2 не является числом, будет использован 0 (ноль)<br /> Array ( [0] => 2.2894597716988 [1] => 3.4341896575482 [2] => 0 [3] => 6.2960143721717 [4] => 49.566804057279 [5] => 24.165247890281 ) ---- vector c - a warning <b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [512] Некорректный входной вектор, пропущен массив значений<br /> NULL ---- vector d - fatal error <b>Пользовательская ОШИБКА</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br /> Фатальная ошибка в строке 35 файла trigger_error.php, PHP 5.2.1 (FreeBSD)<br /> Завершение работы...<br />
Смотрите также
- ErrorException
- error_reporting() — Задаёт, какие ошибки PHP попадут в отчёт
- restore_error_handler() — Восстанавливает предыдущий обработчик ошибок
- trigger_error() — Вызывает пользовательскую ошибку/предупреждение/уведомление
- Константы уровней ошибок
Philip ¶
9 years ago
By this function alone you can not catch fatal errors, there is a simple work around. Below is part of my error.php file which handles errors and exceptions in the application. Before someone complains I'll add that I do not care that I am using globals, this file is part of my mini framework and without the 'config' variable the application would crash anyways.
<?php/**
* Error handler, passes flow over the exception logger with new ErrorException.
*/
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}/**
* Uncaught exception handler.
*/
function log_exception( Exception $e )
{
global $config;
if (
$config["debug"] == true )
{
print "<div style='text-align: center;'>";
print "<h2 style='color: rgb(190, 50, 50);'>Exception Occured:</h2>";
print "<table style='width: 800px; display: inline-block;'>";
print "<tr style='background-color:rgb(230,230,230);'><th style='width: 80px;'>Type</th><td>" . get_class( $e ) . "</td></tr>";
print "<tr style='background-color:rgb(240,240,240);'><th>Message</th><td>{$e->getMessage()}</td></tr>";
print "<tr style='background-color:rgb(230,230,230);'><th>File</th><td>{$e->getFile()}</td></tr>";
print "<tr style='background-color:rgb(240,240,240);'><th>Line</th><td>{$e->getLine()}</td></tr>";
print "</table></div>";
}
else
{
$message = "Type: " . get_class( $e ) . "; Message: {$e->getMessage()}; File: {$e->getFile()}; Line: {$e->getLine()};";
file_put_contents( $config["app_dir"] . "/tmp/logs/exceptions.log", $message . PHP_EOL, FILE_APPEND );
header( "Location: {$config["error_page"]}" );
}
exit();
}
/**
* Checks for a fatal error, work around for set_error_handler not working on fatal errors.
*/
function check_for_fatal()
{
$error = error_get_last();
if ( $error["type"] == E_ERROR )
log_error( $error["type"], $error["message"], $error["file"], $error["line"] );
}register_shutdown_function( "check_for_fatal" );
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
ini_set( "display_errors", "off" );
error_reporting( E_ALL );
elad dot yosifon at gmail dot com ¶
9 years ago
<?php
/**
* throw exceptions based on E_* error types
*/
set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
{
// error was suppressed with the @-operator
if (0 === error_reporting()) { return false;}
switch($err_severity)
{
case E_ERROR: throw new ErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_WARNING: throw new WarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_PARSE: throw new ParseException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_NOTICE: throw new NoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_CORE_ERROR: throw new CoreErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_CORE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_COMPILE_ERROR: throw new CompileErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_COMPILE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_ERROR: throw new UserErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_WARNING: throw new UserWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_NOTICE: throw new UserNoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_STRICT: throw new StrictException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_RECOVERABLE_ERROR: throw new RecoverableErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_DEPRECATED: throw new DeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_DEPRECATED: throw new UserDeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
}
});
class
WarningException extends ErrorException {}
class ParseException extends ErrorException {}
class NoticeException extends ErrorException {}
class CoreErrorException extends ErrorException {}
class CoreWarningException extends ErrorException {}
class CompileErrorException extends ErrorException {}
class CompileWarningException extends ErrorException {}
class UserErrorException extends ErrorException {}
class UserWarningException extends ErrorException {}
class UserNoticeException extends ErrorException {}
class StrictException extends ErrorException {}
class RecoverableErrorException extends ErrorException {}
class DeprecatedException extends ErrorException {}
class UserDeprecatedException extends ErrorException {}
aditycse at gmail dot com ¶
7 years ago
<?php
/**
* Used for logging all php notices,warings and etc in a file when error reporting
* is set and display_errors is off
* @uses used in prod env for logging all type of error of php code in a file for further debugging
* and code performance
* @author Aditya Mehrotra<aditycse@gmail.com>
*/
error_reporting(E_ALL);
ini_set("display_errors", "off");
define('ERROR_LOG_FILE', '/var/www/error.log');/**
* Custom error handler
* @param integer $code
* @param string $description
* @param string $file
* @param interger $line
* @param mixed $context
* @return boolean
*/
function handleError($code, $description, $file = null, $line = null, $context = null) {
$displayErrors = ini_get("display_errors");
$displayErrors = strtolower($displayErrors);
if (error_reporting() === 0 || $displayErrors === "on") {
return false;
}
list($error, $log) = mapErrorCode($code);
$data = array(
'level' => $log,
'code' => $code,
'error' => $error,
'description' => $description,
'file' => $file,
'line' => $line,
'context' => $context,
'path' => $file,
'message' => $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']'
);
return fileLog($data);
}/**
* This method is used to write data in file
* @param mixed $logData
* @param string $fileName
* @return boolean
*/
function fileLog($logData, $fileName = ERROR_LOG_FILE) {
$fh = fopen($fileName, 'a+');
if (is_array($logData)) {
$logData = print_r($logData, 1);
}
$status = fwrite($fh, $logData);
fclose($fh);
return ($status) ? true : false;
}/**
* Map an error code into an Error word, and log location.
*
* @param int $code Error code to map
* @return array Array of error word, and log location.
*/
function mapErrorCode($code) {
$error = $log = null;
switch ($code) {
case E_PARSE:
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$error = 'Fatal Error';
$log = LOG_ERR;
break;
case E_WARNING:
case E_USER_WARNING:
case E_COMPILE_WARNING:
case E_RECOVERABLE_ERROR:
$error = 'Warning';
$log = LOG_WARNING;
break;
case E_NOTICE:
case E_USER_NOTICE:
$error = 'Notice';
$log = LOG_NOTICE;
break;
case E_STRICT:
$error = 'Strict';
$log = LOG_NOTICE;
break;
case E_DEPRECATED:
case E_USER_DEPRECATED:
$error = 'Deprecated';
$log = LOG_NOTICE;
break;
default :
break;
}
return array($error, $log);
}//calling custom error handler
set_error_handler("handleError");print_r($arra); //undefined variable
print_r($dssdfdfgg); //undefined variable
include_once 'file.php'; //No such file or directory
?>
steve962 at gmail dot com ¶
4 years ago
Be careful when using the return value to this function. Because it returns the old handler, you may be tempted to do something like:
<?php
function do_something()
{
$old = set_error_handler(“my_error_handler”);
// Do something you want handled by my_error_handler
set_error_handler($old);
}
?>
This will work, but it will bite you because each time you do this, it will cause a memory leak as the old error handler is put on a stack for the restore_error_handler() function to use.
So always restore the old error handler using that function instead:
<?php
function do_something()
{
set_error_handler(“my_error_handler”);
// Do something you want handled by my_error_handler
restore_error_handler();
}
?>
nizamgok at gmail dot com ¶
13 years ago
I have realized that a few people here mentioned that you cannot capture parse errors (type 4, E_PARSE). This is not true. Here is how I do. I hope this helps someone.
1) Create a "auto_prepend.php" file in the web root and add this:
<?php
register_shutdown_function
('error_alert');
function
error_alert()
{
if(
is_null($e = error_get_last()) === false)
{
mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true));
}
}
?>
2) Then add this "php_value auto_prepend_file /www/auto_prepend.php" to your .htaccess file in the web root.
* make sure you change the email address and the path to the file.
dannykopping at gmail dot com ¶
8 years ago
Keep in mind that, when attempting to set a statically-defined error handler on a namespaced class in PHP >= 5.3, you need to use the class namespace:
<?php
set_error_handler('MyNamespaceBob::errorHandler');
?>
Jacob Slomp ¶
9 years ago
This might be handy if you don't want your clients to see the errors, and you do want to be one step ahead of them.
It emails you the errors even if it's a parse error.
set_error_handler() doesn't work for what I wanted.
<?php
ini_set('log_errors',TRUE);
ini_set('error_log','tiny_uploads/errors.txt');
if(
$_SERVER['REMOTE_ADDR'] != "YOUR IP ADDRESS"){
ini_set('display_errors',false);
}
function
byebye(){$dir = dirname(__FILE__);
if(file_exists($dir."/tiny_uploads/errors.txt")){$errors = file_get_contents($dir."/tiny_uploads/errors.txt");
if(
trim($errors)){$head = "From: php_errors@".str_replace('www.','',$_SERVER['HTTP_HOST'])."rn";$errors .= "---------------------------------------------nn";$errors .= "nnServer Info:nn".print_r($_SERVER, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnCOOKIE:nn".print_r($_COOKIE, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnPOST:nn".print_r($_POST, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnGET:nn".print_r($_GET, 1)."nn";mail("YOUR@EMAIL.COM","PHP Error ".$_SERVER['HTTP_HOST']."", $errors , $head);$fp = fopen($dir."/tiny_uploads/errors.txt","w+");
fputs($fp, "");
fclose($fp);
}
}
}
register_shutdown_function("byebye");
?>
kalle at meizo dot com ¶
13 years ago
This may be of help to someone, who is/was looking for a way to get a backtrace of fatal errors such as maximum memory allocation issues, which can not be handled with user-defined functions, to pin-point the problem:
On a server hosting many sites that share common PHP includes, I set in one spot:
<?php@ini_set ("error_log", "/my/path/php.err-" . $_SERVER ["HTTP_HOST"] . "-" . $_SERVER ["REMOTE_ADDR"] . "-" . $_SERVER ["REQUEST_METHOD"] . "-" . str_replace ("/", "|", $_SERVER ["REQUEST_URI"]));?>
I actually used some additional information too from my software that I omitted, but that way, you'll find errors sorted more neatly in for example:-
/my/path/php.err-website.com-127.0.0.1-GET-path|index.html?xyz
And that at least helped me tremendously to then further pin-point where the problem is, as opposed to before just seeing the out of memory and not knowing which site/page it was on (as the PHP error only contains the very latest PHP code where it ran out of memory, which usually is just a shared included file, not the actual page).
webmaster at paramiliar dot com ¶
15 years ago
We needed to use an error handler to handle SQL errors while passing the query along so the query is also logged and this is what we came up with, its kind of an ugly bridge but it works 100%
<?phpfunction myErrorHandler($errno, $errstr, $errfile, $errline){
switch ($errno) {
case E_USER_ERROR:
if ($errstr == "(SQL)"){
// handling an sql error
echo "<b>SQL Error</b> [$errno] " . SQLMESSAGE . "<br />n";
echo "Query : " . SQLQUERY . "<br />n";
echo "On line " . SQLERRORLINE . " in file " . SQLERRORFILE . " ";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Aborting...<br />n";
} else {
echo "<b>My ERROR</b> [$errno] $errstr<br />n";
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Aborting...<br />n";
}
exit(1);
break;
case
E_USER_WARNING:
case E_USER_NOTICE:
}
/* Don't execute PHP internal error handler */
return true;
}// function to test the error handlingfunction sqlerrorhandler($ERROR, $QUERY, $PHPFILE, $LINE){
define("SQLQUERY", $QUERY);
define("SQLMESSAGE", $ERROR);
define("SQLERRORLINE", $LINE);
define("SQLERRORFILE", $PHPFILE);
trigger_error("(SQL)", E_USER_ERROR);
}set_error_handler("myErrorHandler");// trigger an sql error
$query = "SELECT * FROM tbl LIMIT 1";
$sql = @mysql_query($query)
or sqlerrorhandler("(".mysql_errno().") ".mysql_error(), $query, $_SERVER['PHP_SELF'], __LINE__);?>
dorphalsig at NOSPAMgmail dot com ¶
11 years ago
This actually works to catch Fatal errors...
<?phpfunction shutdown()
{
$a=error_get_last();
if(
$a==null)
echo
"No errors";
else
print_r($a);
}
register_shutdown_function('shutdown');ini_set('max_execution_time',1 );sleep(3);?>
it will output
Array ( [type] => 1 [message] => Maximum execution time of 1 second exceeded [file] => /path/to/file_name.php [line] => 136 )
Steffen Staehle ¶
18 years ago
Two notes on using set_error_handler() on behaviour that I noticed when migrating an application from php 4.2.1 to php 4.3.9 (I do not yet have php 5.0 available, this might not apply there!).
1. setting the system error handler
If you want to set the standard php error handler again, after having set your own error handler, this works in php 4.2.1 by passing in an empty string:
<?phpfunction my_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// do something useful
// ...
}$last_handler = set_error_handler("my_handler");// after this, $last_handler == ""
// restore standard error handler
$last_handler = set_error_handler("");// after this, $last_handler == "my_handler"?>
The very same code now raises an error in php 4.3.9:
set_error_handler() expects argument 1, '', to be a valid callback
(Since the return value of the first call to set_error_handler() is still the empty string "", I don't see how this can be done any more. I don't really need this, because I use my own handlers as shown below, but it might be good to be aware of this.)
2. setting your own 'second level' handler
If you have set your own error handler, and want to replace it by another one (other than the standard php error handler) while it is being executed, note that the return value of set_error_handler when used INSIDE the error handler is "" instead of the name of the previous handler! This is not too surprising, because during execution of your self defined error handler, php replaces it with the standard php error handler to avoid infinite loops in case of problems inside the handler. This is only interesting if you want nested handlers as I do. Background of my design:
1st level handler: log into DB
2nd level handler: log into flat file (if log into DB fails)
3rd level handler: print to stdout (if log into flat file fails) (this is the sytem handler, finally).
<?phpfunction my_fallback_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// do something useful
// ...
} // my_fallback_handlerfunction my_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// but we want to have a fallback handler different
// to the standard error handler
$last_handler = set_error_handler("my_fallback_handler");// I expected $last_handler == "my_handler"
// (which it would outside my_handler())
// but here it is the empty string ""
// do something useful
// ...
// now set the 1st level handler again:
// (do NOT use $last_handler as argument,
// because it equals "")
$last_handler = set_error_handler("my_handler");
}
// my_handler$last_handler = set_error_handler("my_handler");?>
Anonymous ¶
18 years ago
It seems that when you're letting PHP know that you have a custom error handler, you're not able to -update/set new- variables inside the class. Example:
<?phpclass error {
var
$error;
function
error() {$this->setIni(); // this causes PHP to ignore all other changes to the class.}
function
handler() {
echo
$this->error.'!!';
}
function
setText($text) {$this->error = $text;
}
function
setIni() {set_error_handler(array($this, 'handler'));
}
}
$eh = new error;$eh->setText('Error! <br>'); // this will not be saved
trigger_error('text', E_USER_ERROR);// prints '!!'?>
How it should be done:
<?phpclass error {
var
$error;
function
error() {// dont let PHP know of our error handler yet}
function
handler() {
echo
$this->error.'!!';
}
function
setText($text) {$this->error = $text;
}
function
setIni() {set_error_handler(array($this, 'handler'));
}
}
$eh = new error;$eh->setText('Error! <br>'); // this WILL work$eh->setIni(); // call this method when you're ready with configuring the class. All other methods that will be called will have no effect on the errorHandling by PHP
trigger_error('text', E_USER_ERROR);// prints 'Error! <br>!!'?>
silkensedai at online dot fr ¶
15 years ago
i made an error handler that print also the backtrace and that can die on some errors. It can be useful if you want to die on every error you find.
<?phpfunction my_error_handler($errno, $errstr, $errfile, $errline){
$errno = $errno & error_reporting();
if($errno == 0) return;
if(!defined('E_STRICT')) define('E_STRICT', 2048);
if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096);
print "<pre>n<b>";
switch($errno){
case E_ERROR: print "Error"; break;
case E_WARNING: print "Warning"; break;
case E_PARSE: print "Parse Error"; break;
case E_NOTICE: print "Notice"; break;
case E_CORE_ERROR: print "Core Error"; break;
case E_CORE_WARNING: print "Core Warning"; break;
case E_COMPILE_ERROR: print "Compile Error"; break;
case E_COMPILE_WARNING: print "Compile Warning"; break;
case E_USER_ERROR: print "User Error"; break;
case E_USER_WARNING: print "User Warning"; break;
case E_USER_NOTICE: print "User Notice"; break;
case E_STRICT: print "Strict Notice"; break;
case E_RECOVERABLE_ERROR: print "Recoverable Error"; break;
default: print "Unknown error ($errno)"; break;
}
print ":</b> <i>$errstr</i> in <b>$errfile</b> on line <b>$errline</b>n";
if(function_exists('debug_backtrace')){
//print "backtrace:n";
$backtrace = debug_backtrace();
array_shift($backtrace);
foreach($backtrace as $i=>$l){
print "[$i] in function <b>{$l['class']}{$l['type']}{$l['function']}</b>";
if($l['file']) print " in <b>{$l['file']}</b>";
if($l['line']) print " on line <b>{$l['line']}</b>";
print "n";
}
}
print "n</pre>";
if(isset($GLOBALS['error_fatal'])){
if($GLOBALS['error_fatal'] & $errno) die('fatal');
}
}
function
error_fatal($mask = NULL){
if(!is_null($mask)){
$GLOBALS['error_fatal'] = $mask;
}elseif(!isset($GLOBALS['die_on'])){
$GLOBALS['error_fatal'] = 0;
}
return $GLOBALS['error_fatal'];
}?>
Usage :
<?php
error_reporting(E_ALL); // will report all errors
set_error_handler('my_error_handler');
error_fatal(E_ALL^E_NOTICE); // will die on any error except E_NOTICE
?>
wfinn at riverbed dot com ¶
14 years ago
"The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called."
This is not exactly true. set_error_handler() can't handle them, but ob_start() can handle at least E_ERROR.
<?phpfunction error_handler($output)
{
$error = error_get_last();
$output = "";
foreach ($error as $info => $string)
$output .= "{$info}: {$string}n";
return $output;
}ob_start('error_handler');will_this_undefined_function_raise_an_error();?>
francois vespa ¶
12 years ago
This is a note when using php from the terminal (the CLI interface). From the command line, even if you have some kind of error user handler function so STDERR will not display, fatal errors will still cause the PHP interpreter to display error text. There is nothing you can do about that php-wise. If using UNIX/Linux, you can add " 2>/dev/null" at the end of your command to force STDERR not to show
Anonymous ¶
17 years ago
To honor the value of PHP's error_reporting() function, use:
<?
if( ($level & error_reporting()) == 0 ) return;
?>
roy ¶
20 years ago
Useful thing to note - if your error handler throws an error in itself, PHP is smart enough to use the deault error handler to handle it. This way, you don't end up in infinite flaming loops of death. This seems to be true, at least, in PHP 4.2.
('Course, there are ways to create your handler to handle even this situation, but it's probably best left this way for general purposes.)
jtrick77 at gmail dot com ¶
9 years ago
For anyone interested in the actual translated error codes and their meanings:
1 E_ERROR (integer) Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.
2 E_WARNING (integer) Run-time warnings (non-fatal errors). Execution of the script is not halted.
4 E_PARSE (integer) Compile-time parse errors. Parse errors should only be generated by the parser.
8 E_NOTICE (integer) Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
16 E_CORE_ERROR (integer) Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP.
32 E_CORE_WARNING (integer) Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP.
64 E_COMPILE_ERROR (integer) Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.
128 E_COMPILE_WARNING (integer) Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.
256 E_USER_ERROR (integer) User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error().
512 E_USER_WARNING (integer) User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function trigger_error().
1024 E_USER_NOTICE (integer) User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error().
2048 E_STRICT (integer) Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. Since PHP 5 but not included in E_ALL until PHP 5.4.0
4096 E_RECOVERABLE_ERROR (integer) Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR. Since PHP 5.2.0
8192 E_DEPRECATED (integer) Run-time notices. Enable this to receive warnings about code that will not work in future versions. Since PHP 5.3.0
16384 E_USER_DEPRECATED (integer) User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error(). Since PHP 5.3.0
32767 E_ALL (integer) All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0. 32767 in PHP 5.4.x, 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously
(Copied from http://php.net/manual/en/errorfunc.constants.php)
nicolas dot grekas+php at gmail dot com ¶
9 years ago
If you want to be sure that the native PHP error handler is called without resetting the handler stack (as set_error_handler(null) does), you can simply call set_error_handler with $error_types set to zero. This can be especially use full in conjunction with e.g. error_get_last():
<?php// var_dump or anything else, as this will never be called because of the 0
set_error_handler('var_dump', 0);
@$undef_var;
restore_error_handler();// error_get_last() is now in a well known state:
// Undefined variable: undef_var... // Do something$e = error_get_last();
...
?>
phil at propcom dot co dot uk ¶
9 years ago
It is important to note that the registered SPL autoloader will NOT be called if an E_STRICT error triggers the error handler which, in turn, tries to use classes which are not yet loaded.
In this instance, you should manually load classes required by the error handler.
phpmanual at NO_SPHAMnetebb dot com ¶
19 years ago
Given this code:
class CallbackClass {
function CallbackFunction() {
// refers to $this
}
function StaticFunction() {
// doesn't refer to $this
}
}
function NonClassFunction() {
}
there appear to be 3 ways to set a callback function in PHP (using set_error_handler() as an example):
1: set_error_handler('NonClassFunction');
2: set_error_handler(array('CallbackClass', 'StaticFunction'));
3: $o =& new CallbackClass();
set_error_handler(array($o, 'CallbackFunction'));
The following may also prove useful:
class CallbackClass {
function CallbackClass() {
set_error_handler(array(&$this, 'CallbackFunction')); // the & is important
}
function CallbackFunction() {
// refers to $this
}
}
The documentation is not clear in outlining these three examples.
stepheneliotdewey at GmailDotCom ¶
15 years ago
The manual states:
"errcontext will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context."
But do you know WHY you must not modify the error context? It appears that errcontext is (in effect if not literally) created by taking $GLOBALS and adding the non-global local variables as additional entries in that array, then passing the whole thing *by reference*.
(You can prove this to be true if you set up a custom error handler and then print_r($errcontext) within it, because $GLOBALS will be printed as a recursive array).
In other words, the language in the manual is misleading, because errcontext is NOT a copy of the variables that existed when the error WAS triggered, but rather is a reference to the *existing LIVE variables* in the calling script.
This includes superglobal variables like $_SERVER, $_POST, $_GET, etc., as well as all user-defined variables in scope.
The significance of that is that if you modify errcontext, you will be modifying those other variables, not just for the life of your error handling function, but for the life of the calling script as well.
That doesn't matter if you plan to halt execution in your error handling function, but it will lead to unexpected behavior if you modify $errcontext and then return to the program's normal flow after handling the error, because the variables will stay modified. For example, if you unset $_SERVER in your custom error handling function, it will remain unset once the function is over and you have returned to the page that generated the error.
This should be made clearer in the manual, starting by marking errhandler with an ampersand (&) for passage by reference in the "Parameters" section above, like so:
handler ( int $errno, string $errstr [, string $errfile [, int $errline [, array &$errcontext]]] )
Marcelius ¶
14 years ago
Another way to catch PHP's fatal errors:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
function
shutdown(){
$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if (
$isError){
echo "Script execution halted ({$error['message']})";
} else {
echo "Script completed";
}
}register_shutdown_function('shutdown');
?>
Note that this will only catch runtime errors. So calling a method in a non existing class, or declaring a function twice does not trigger the shutdown handler.
periklis ¶
12 years ago
How to handle fatal errors in php 5.2:
<?php
register_shutdown_function
('shutdownFunction');
function
shutDownFunction() {$error = error_get_last();
if (
$error['type'] == 1) {//do your stuff }
}
?>
mmtache at yahoo dot com ¶
19 years ago
The @ operator sets the error_reporting() value to 0.
This means you can use it with your own Error Handler too. for example:
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
if (error_reporting())
echo $errmsg;
}
set_error_handler("userErrorHandler");
function test(){
trigger_error("Error Message", E_USER_WARNING);
}
@test(); // doesn't output anything
Klauss ¶
5 years ago
Hi everyone. I don't know if it is an old behavior of previous versions, but currently you can set exception and error handlers as private or protected methos, if, only if, you call `set_exception_handler()` or `set_error_handler()` within a context that can access the method.
Example:
<?PHP
$Handler = new class ()
{
public function __construct ()
{
set_error_handler([&$this, 'HandleError']);
set_exception_handler([&$this, 'HandleException']);
}
protected function HandleError ( $Code, $Message, $File = null, $Line = 0, $Context = [] )
{
// Handle error here.
}
private function HandleException ( $Exception )
{
// Handle exception here.
}
}
?>
NOTE: these methods must match the callbacks parameters signatures.
a dot ross at amdev dot eu ¶
4 years ago
I'm missing a way to chain error handlers. It's not something offered by set_error_handler. You have to jump through some hoops to get it to work, but it *is* quite possible, by making use of the return value of the function. Here's an example:
<?
$previous = set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$previous) {
/* Your custom error handling code here. */
// If another error handler was defined, call it.
if ($previous) {
return $previous($errno, $errstr, $errfile, $errline, $errcontext);
} else {
// Use the standard PHP error handler.
return false;
}
});
?>
kaioker ¶
1 year ago
super simple error code to human readable conversion:
function prettycode($code){
return $code == 0 ? "FATAL" : array_search($code, get_defined_constants(true)['Core']);
}
Alex M ¶
1 year ago
If you are new to programming and you would like to know how to add a combination of those error reporting values to .htaccess file. Here's a small guide.
With PHP function error_reporting we can add together option with bitwise add operator | . But we can't use those constants in htaccess file and in my case I have no idea how to add bitwise number.
So, solution can be casting selected options to int:
echo (int)(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR) ;
->263
Then you can use 263 in .htaccess
php_value error_reporting 263
In my case I needed those errors to be displayed for my debugging server. But the combination can be different from mine.
David Spector ¶
2 years ago
The PHP manual is not very clear about how to handle @ operator error messages.
Here is working code:
// Do nothing if @ operator
$errLevel=error_reporting(E_ALL);
if ($errLevel===0)
return true; // ignore @ prefixed expression errors
chris at ocproducts dot com ¶
6 years ago
Note that error handlers don't run recursively. If you have an error while an error handler is running (in the error handler itself or code called from it) then you won't get the error handler called again.
This has subtle ramifications for $php_errormsg. If you are relying on your error handler to suppress certain kinds of error message from going into $php_errormsg (via return true; because error_reporting doesn't affect $php_errormsg setting) then this will not work for any code called within that error handler.
devermin at ti0n dot net ¶
12 years ago
At work I have some code with errors that uncatched are the causes of integrity loss (people calling web services with file_get_contents that fails silently and afterwards insert garbage in the database).
here is the solution I found to transform a specific set of errors into exception and afterwards be able to selectively act (with the error code) regarding categories :
<?php
ini_set
('error_reporting',E_ALL^E_NOTICE);
## first 10 bits reserved for the initial error numberdefine('EMASK',(~0)<<10);define('ECODEMASK',~EMASK);## categoriesdefine('IOERROR', 1<<10);define('EMPTYPARMS', 1<<11);define('FAILURE', 1<<12);## string error patterns => code
$catch_me=array("/^(file_get_contents)((.*)).*failed to open stream: (.*)/ " =>
array (
'mesg' => "IO::Failed to open stream with",'code' => IOERROR | FAILURE),"/^fopen(.*): Filename cannot be empty/" =>
array(
'msg' => "Parameters::empty",'code' => EMPTYPARMS)
);
function
error_2_exception($errno, $errstr, $errfile, $errline,$context) {
global
$catch_me;
foreach (
$catch_me as $regexp => $res) {
if(
preg_match($regexp,$errstr,$match)){
throw new
Exception($res['mesg'],$res['code']|( $errno & EMASK ) );
}
}
/* switch back to PHP internal error handler */return false;
}
## => want to catch this one$f=file_get_contents("mlsdkfm");## dont want to break existing wrong behaviour yet (so not caught)$f=file_get_contents('');## magicset_error_handler("error_2_exception");## behaviour remains the same$f=file_get_contents('');
try {
## web services that dont work now raise an exception o/$f=file_get_contents("mlsdkfm");
} catch(
Exception $e) {## and I can group my exception by categoryecho ( $e->getCode() & FAILURE ) ? "nEPIC FAILn" : "nbegnine";
}
?>
ash ¶
15 years ago
error handling function that handles both errors and exceptions; also features a backtrace including possible function arguments.
<?php
$cfg
= array();
$cfg['debug'] = 1;
$cfg['adminEmail'] = 'name@domain.tld';
function
errorHandler($errno, $errstr='', $errfile='', $errline='')
{
// if error has been supressed with an @
if (error_reporting() == 0) {
return;
}
global
$cfg;// check if function has been called by an exception
if(func_num_args() == 5) {
// called by trigger_error()
$exception = null;
list($errno, $errstr, $errfile, $errline) = func_get_args();$backtrace = array_reverse(debug_backtrace());
}else {
// caught exception
$exc = func_get_arg(0);
$errno = $exc->getCode();
$errstr = $exc->getMessage();
$errfile = $exc->getFile();
$errline = $exc->getLine();$backtrace = $exc->getTrace();
}$errorType = array (
E_ERROR => 'ERROR',
E_WARNING => 'WARNING',
E_PARSE => 'PARSING ERROR',
E_NOTICE => 'NOTICE',
E_CORE_ERROR => 'CORE ERROR',
E_CORE_WARNING => 'CORE WARNING',
E_COMPILE_ERROR => 'COMPILE ERROR',
E_COMPILE_WARNING => 'COMPILE WARNING',
E_USER_ERROR => 'USER ERROR',
E_USER_WARNING => 'USER WARNING',
E_USER_NOTICE => 'USER NOTICE',
E_STRICT => 'STRICT NOTICE',
E_RECOVERABLE_ERROR => 'RECOVERABLE ERROR'
);// create error message
if (array_key_exists($errno, $errorType)) {
$err = $errorType[$errno];
} else {
$err = 'CAUGHT EXCEPTION';
}$errMsg = "$err: $errstr in $errfile on line $errline";// start backtrace
foreach ($backtrace as $v) {
if (isset(
$v['class'])) {$trace = 'in class '.$v['class'].'::'.$v['function'].'(';
if (isset(
$v['args'])) {
$separator = '';
foreach(
$v['args'] as $arg ) {
$trace .= "$separator".getArgument($arg);
$separator = ', ';
}
}
$trace .= ')';
}
elseif (isset(
$v['function']) && empty($trace)) {
$trace = 'in function '.$v['function'].'(';
if (!empty($v['args'])) {$separator = '';
foreach(
$v['args'] as $arg ) {
$trace .= "$separator".getArgument($arg);
$separator = ', ';
}
}
$trace .= ')';
}
}// display error msg, if debug is enabled
if($cfg['debug'] == 1) {
echo '<h2>Debug Msg</h2>'.nl2br($errMsg).'<br />
Trace: '.nl2br($trace).'<br />';
}// what to do
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
return;
break;
default:
if(
$cfg['debug'] == 0){
// send email to admin
if(!empty($cfg['adminEmail'])) {
@mail($cfg['adminEmail'],'critical error on '.$_SERVER['HTTP_HOST'], $errorText,
'From: Error Handler');
}
// end and display error msg
exit(displayClientMessage());
}
else
exit('<p>aborting.</p>');
break;
}
}
// end of errorHandler()function displayClientMessage()
{
echo 'some html page with error message';
}
function
getArgument($arg)
{
switch (strtolower(gettype($arg))) {
case
'string':
return( '"'.str_replace( array("n"), array(''), $arg ).'"' );
case
'boolean':
return (bool)$arg;
case
'object':
return 'object('.get_class($arg).')';
case
'array':
$ret = 'array(';
$separtor = '';
foreach (
$arg as $k => $v) {
$ret .= $separtor.getArgument($k).' => '.getArgument($v);
$separtor = ', ';
}
$ret .= ')';
return
$ret;
case
'resource':
return 'resource('.get_resource_type($arg).')';
default:
return
var_export($arg, true);
}
}?>
(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP
set_error_handler —
Задаёт пользовательский обработчик ошибок
Описание
set_error_handler(?callable $callback
, int $error_levels
= E_ALL
): ?callable
Функция может быть использована для определения пользовательских обработчиков
ошибок во время выполнения, например, в приложениях, которые должны выполнять
очистку файлов/данных в случае возникновения критической ошибки
или при инициировании ошибки в ответ на определённые условия
(используя функцию trigger_error()).
Важно помнить, что стандартный обработчик ошибок PHP не будет обрабатывать
никакие типы ошибок, определённые в error_levels
,
пока callback-функция не вернёт false
. Пользовательский обработчик будет
вызываться в случае возникновения любой ошибке, независимо от настроек, заданных функцией
error_reporting.
Также обратите внимание, что обработчик обязан при необходимости остановить
выполнение скрипта, вызвав функцию exit().
Если происходит возврат из обработчика ошибок,
управление передаётся следующему выражению, стоящему за тем, что вызвало ошибку.
Ошибки следующих типов не могут быть обработаны пользователем:
E_ERROR
, E_PARSE
,
E_CORE_ERROR
, E_CORE_WARNING
,
E_COMPILE_ERROR
,
E_COMPILE_WARNING
независимо от того, где они были сгенерированы и большинство
ошибок E_STRICT
, произошедших в файле, где вызвана
функция set_error_handler().
Если ошибки возникают до запуска скрипта (например, пока файл загружается),
пользовательский обработчик не будет вызываться, если на этот момент он
ещё не зарегистрирован.
Список параметров
-
callback
-
Если передано значение
null
, обработчик сбрасывается в состояние по умолчанию.
В противном случае обработчик представляет собой callback-функцию со следующей сигнатурой:handler(
int$errno
,
string$errstr
,
string$errfile
= ?,
int$errline
= ?,
array$errcontext
= ?
): bool-
errno
-
В первый аргументerrno
будет передан уровень
ошибки в виде целого числа.
-
errstr
-
Во второй аргументerrstr
будет передано сообщение
об ошибке в виде строки.
-
errfile
-
Если функция обратного вызова принимает третий параметр
errfile
, то в него будет передано
имя файла, в котором произошла ошибка, в виде строки.
-
errline
-
Если функция обратного вызова принимает четвёртый параметр
errline
, то в него будет передан
номер строки, в которой произошла ошибка, в виде целого
числа.
-
errcontext
-
Если функция обратного вызова принимает пятый параметр
errcontext
, то в него будет передан
массив указателей на активную таблицу символов в точке, где
произошла ошибка. Другими словами,errcontext
будет содержать массив всех переменных, существующих в области
видимости, где произошла ошибка. Пользовательские обработчики ошибок не
должны изменять этот контекст.
Внимание
Этот параметр объявлен УСТАРЕВШИМ начиная с PHP 7.2.0 и
был УДАЛЁН в PHP 8.0.0. Если в вашей функции этот
параметр используется и для него не задано значение по умолчанию, то при
вызове функции обработчика будет выдана ошибка «too few arguments».
Если функция возвращает
false
, управление передаётся встроенному
обработчику ошибок. -
-
error_levels
-
Может использоваться для задания маски, в соответствии с которой будет
вызыватьсяcallback
, по аналогии с
ini-настройкой error_reporting,
которая отвечает за то, какие ошибки будут показаны в отчёте. Без этой
маскиcallback
будет вызываться для
обработки всех происходящих ошибок, вне зависимости от настроек в
error_reporting.
Возвращаемые значения
Возвращает ранее определённый обработчик ошибок (если есть) Если на данный момент используется встроенный обработчик, функция
вернёт null
. Если предыдущий определённый обработчик является методом класса, функция вернёт массив,
содержащий имя класса и имя метода.
Список изменений
Версия | Описание |
---|---|
8.0.0 |
Параметр errcontext был удалён и больше не передаётся впользовательскую функцию обработки ошибок. |
7.2.0 |
Параметр errcontext объявлен устаревшим. Теперь при егоиспользовании будет вызываться ошибка уровня E_DEPRECATED .
|
Примеры
Пример #1
Обработка ошибок с помощью функций set_error_handler()
и trigger_error()
Пример ниже демонстрирует обработку внутренних исключений путём
вызова ошибок разных типов и их обработки пользовательской функцией:
<?php
// функция обработки ошибок
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// Этот код ошибки не включён в error_reporting,
// так что пусть обрабатываются стандартным обработчиком ошибок PHP
return false;
}// может потребоваться экранирование $errstr:
$errstr = htmlspecialchars($errstr);
switch (
$errno) {
case E_USER_ERROR:
echo "<b>Пользовательская ОШИБКА</b> [$errno] $errstr<br />n";
echo " Фатальная ошибка в строке $errline файла $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Завершение работы...<br />n";
exit(1);
case
E_USER_WARNING:
echo "<b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [$errno] $errstr<br />n";
break;
case
E_USER_NOTICE:
echo "<b>Пользовательское УВЕДОМЛЕНИЕ</b> [$errno] $errstr<br />n";
break;
default:
echo
"Неизвестная ошибка: [$errno] $errstr<br />n";
break;
}/* Не запускаем внутренний обработчик ошибок PHP */
return true;
}// функция для тестирования обработчика ошибок
function scale_by_log($vect, $scale)
{
if (!is_numeric($scale) || $scale <= 0) {
trigger_error("log(x) для x <= 0 не определён, вы используете: scale = $scale", E_USER_ERROR);
}
if (!
is_array($vect)) {
trigger_error("Некорректный входной вектор, пропущен массив значений", E_USER_WARNING);
return null;
}$temp = array();
foreach($vect as $pos => $value) {
if (!is_numeric($value)) {
trigger_error("Значение на позиции $pos не является числом, будет использован 0 (ноль)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}
return
$temp;
}// переключаемся на пользовательский обработчик
$old_error_handler = set_error_handler("myErrorHandler");// вызовем несколько ошибок, во-первых, определим массив с нечисловым элементом
echo "vector an";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);// теперь создадим ещё один массив
echo "----nvector b - a notice (b = log(PI) * a)n";
/* Значение на позиции $pos не является числом, будет использован 0 (ноль)*/
$b = scale_by_log($a, M_PI);
print_r($b);// проблема, мы передаём строку вместо массива
echo "----nvector c - a warningn";
/* Некорректный входной вектор, пропущен массив значений */
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL
// критическая ошибка, логарифм от неположительного числа не определён
echo "----nvector d - fatal errorn";
/* log(x) для x <= 0 не определён, вы используете: scale = $scale */
$d = scale_by_log($a, -2.5);
var_dump($d); // До сюда не дойдём никогда
?>
Результатом выполнения данного примера
будет что-то подобное:
vector a Array ( [0] => 2 [1] => 3 [2] => foo [3] => 5.5 [4] => 43.3 [5] => 21.11 ) ---- vector b - a notice (b = log(PI) * a) <b>Пользовательское УВЕДОМЛЕНИЕ</b> [1024] Значение на позиции 2 не является числом, будет использован 0 (ноль)<br /> Array ( [0] => 2.2894597716988 [1] => 3.4341896575482 [2] => 0 [3] => 6.2960143721717 [4] => 49.566804057279 [5] => 24.165247890281 ) ---- vector c - a warning <b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [512] Некорректный входной вектор, пропущен массив значений<br /> NULL ---- vector d - fatal error <b>Пользовательская ОШИБКА</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br /> Фатальная ошибка в строке 35 файла trigger_error.php, PHP 5.2.1 (FreeBSD)<br /> Завершение работы...<br />
Смотрите также
- ErrorException
- error_reporting() — Задаёт, какие ошибки PHP попадут в отчёт
- restore_error_handler() — Восстанавливает предыдущий обработчик ошибок
- trigger_error() — Вызывает пользовательскую ошибку/предупреждение/уведомление
- Константы уровней ошибок
Philip ¶
10 years ago
By this function alone you can not catch fatal errors, there is a simple work around. Below is part of my error.php file which handles errors and exceptions in the application. Before someone complains I'll add that I do not care that I am using globals, this file is part of my mini framework and without the 'config' variable the application would crash anyways.
<?php/**
* Error handler, passes flow over the exception logger with new ErrorException.
*/
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}/**
* Uncaught exception handler.
*/
function log_exception( Exception $e )
{
global $config;
if (
$config["debug"] == true )
{
print "<div style='text-align: center;'>";
print "<h2 style='color: rgb(190, 50, 50);'>Exception Occured:</h2>";
print "<table style='width: 800px; display: inline-block;'>";
print "<tr style='background-color:rgb(230,230,230);'><th style='width: 80px;'>Type</th><td>" . get_class( $e ) . "</td></tr>";
print "<tr style='background-color:rgb(240,240,240);'><th>Message</th><td>{$e->getMessage()}</td></tr>";
print "<tr style='background-color:rgb(230,230,230);'><th>File</th><td>{$e->getFile()}</td></tr>";
print "<tr style='background-color:rgb(240,240,240);'><th>Line</th><td>{$e->getLine()}</td></tr>";
print "</table></div>";
}
else
{
$message = "Type: " . get_class( $e ) . "; Message: {$e->getMessage()}; File: {$e->getFile()}; Line: {$e->getLine()};";
file_put_contents( $config["app_dir"] . "/tmp/logs/exceptions.log", $message . PHP_EOL, FILE_APPEND );
header( "Location: {$config["error_page"]}" );
}
exit();
}
/**
* Checks for a fatal error, work around for set_error_handler not working on fatal errors.
*/
function check_for_fatal()
{
$error = error_get_last();
if ( $error["type"] == E_ERROR )
log_error( $error["type"], $error["message"], $error["file"], $error["line"] );
}register_shutdown_function( "check_for_fatal" );
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
ini_set( "display_errors", "off" );
error_reporting( E_ALL );
elad dot yosifon at gmail dot com ¶
9 years ago
<?php
/**
* throw exceptions based on E_* error types
*/
set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
{
// error was suppressed with the @-operator
if (0 === error_reporting()) { return false;}
switch($err_severity)
{
case E_ERROR: throw new ErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_WARNING: throw new WarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_PARSE: throw new ParseException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_NOTICE: throw new NoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_CORE_ERROR: throw new CoreErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_CORE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_COMPILE_ERROR: throw new CompileErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_COMPILE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_ERROR: throw new UserErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_WARNING: throw new UserWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_NOTICE: throw new UserNoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_STRICT: throw new StrictException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_RECOVERABLE_ERROR: throw new RecoverableErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_DEPRECATED: throw new DeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
case E_USER_DEPRECATED: throw new UserDeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
}
});
class
WarningException extends ErrorException {}
class ParseException extends ErrorException {}
class NoticeException extends ErrorException {}
class CoreErrorException extends ErrorException {}
class CoreWarningException extends ErrorException {}
class CompileErrorException extends ErrorException {}
class CompileWarningException extends ErrorException {}
class UserErrorException extends ErrorException {}
class UserWarningException extends ErrorException {}
class UserNoticeException extends ErrorException {}
class StrictException extends ErrorException {}
class RecoverableErrorException extends ErrorException {}
class DeprecatedException extends ErrorException {}
class UserDeprecatedException extends ErrorException {}
aditycse at gmail dot com ¶
7 years ago
<?php
/**
* Used for logging all php notices,warings and etc in a file when error reporting
* is set and display_errors is off
* @uses used in prod env for logging all type of error of php code in a file for further debugging
* and code performance
* @author Aditya Mehrotra<aditycse@gmail.com>
*/
error_reporting(E_ALL);
ini_set("display_errors", "off");
define('ERROR_LOG_FILE', '/var/www/error.log');/**
* Custom error handler
* @param integer $code
* @param string $description
* @param string $file
* @param interger $line
* @param mixed $context
* @return boolean
*/
function handleError($code, $description, $file = null, $line = null, $context = null) {
$displayErrors = ini_get("display_errors");
$displayErrors = strtolower($displayErrors);
if (error_reporting() === 0 || $displayErrors === "on") {
return false;
}
list($error, $log) = mapErrorCode($code);
$data = array(
'level' => $log,
'code' => $code,
'error' => $error,
'description' => $description,
'file' => $file,
'line' => $line,
'context' => $context,
'path' => $file,
'message' => $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']'
);
return fileLog($data);
}/**
* This method is used to write data in file
* @param mixed $logData
* @param string $fileName
* @return boolean
*/
function fileLog($logData, $fileName = ERROR_LOG_FILE) {
$fh = fopen($fileName, 'a+');
if (is_array($logData)) {
$logData = print_r($logData, 1);
}
$status = fwrite($fh, $logData);
fclose($fh);
return ($status) ? true : false;
}/**
* Map an error code into an Error word, and log location.
*
* @param int $code Error code to map
* @return array Array of error word, and log location.
*/
function mapErrorCode($code) {
$error = $log = null;
switch ($code) {
case E_PARSE:
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$error = 'Fatal Error';
$log = LOG_ERR;
break;
case E_WARNING:
case E_USER_WARNING:
case E_COMPILE_WARNING:
case E_RECOVERABLE_ERROR:
$error = 'Warning';
$log = LOG_WARNING;
break;
case E_NOTICE:
case E_USER_NOTICE:
$error = 'Notice';
$log = LOG_NOTICE;
break;
case E_STRICT:
$error = 'Strict';
$log = LOG_NOTICE;
break;
case E_DEPRECATED:
case E_USER_DEPRECATED:
$error = 'Deprecated';
$log = LOG_NOTICE;
break;
default :
break;
}
return array($error, $log);
}//calling custom error handler
set_error_handler("handleError");print_r($arra); //undefined variable
print_r($dssdfdfgg); //undefined variable
include_once 'file.php'; //No such file or directory
?>
steve962 at gmail dot com ¶
5 years ago
Be careful when using the return value to this function. Because it returns the old handler, you may be tempted to do something like:
<?php
function do_something()
{
$old = set_error_handler(“my_error_handler”);
// Do something you want handled by my_error_handler
set_error_handler($old);
}
?>
This will work, but it will bite you because each time you do this, it will cause a memory leak as the old error handler is put on a stack for the restore_error_handler() function to use.
So always restore the old error handler using that function instead:
<?php
function do_something()
{
set_error_handler(“my_error_handler”);
// Do something you want handled by my_error_handler
restore_error_handler();
}
?>
nizamgok at gmail dot com ¶
14 years ago
I have realized that a few people here mentioned that you cannot capture parse errors (type 4, E_PARSE). This is not true. Here is how I do. I hope this helps someone.
1) Create a "auto_prepend.php" file in the web root and add this:
<?php
register_shutdown_function
('error_alert');
function
error_alert()
{
if(
is_null($e = error_get_last()) === false)
{
mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true));
}
}
?>
2) Then add this "php_value auto_prepend_file /www/auto_prepend.php" to your .htaccess file in the web root.
* make sure you change the email address and the path to the file.
dannykopping at gmail dot com ¶
9 years ago
Keep in mind that, when attempting to set a statically-defined error handler on a namespaced class in PHP >= 5.3, you need to use the class namespace:
<?php
set_error_handler('\My\Namespace\Bob::errorHandler');
?>
Jacob Slomp ¶
10 years ago
This might be handy if you don't want your clients to see the errors, and you do want to be one step ahead of them.
It emails you the errors even if it's a parse error.
set_error_handler() doesn't work for what I wanted.
<?php
ini_set('log_errors',TRUE);
ini_set('error_log','tiny_uploads/errors.txt');
if(
$_SERVER['REMOTE_ADDR'] != "YOUR IP ADDRESS"){
ini_set('display_errors',false);
}
function
byebye(){$dir = dirname(__FILE__);
if(file_exists($dir."/tiny_uploads/errors.txt")){$errors = file_get_contents($dir."/tiny_uploads/errors.txt");
if(
trim($errors)){$head = "From: php_errors@".str_replace('www.','',$_SERVER['HTTP_HOST'])."rn";$errors .= "---------------------------------------------nn";$errors .= "nnServer Info:nn".print_r($_SERVER, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnCOOKIE:nn".print_r($_COOKIE, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnPOST:nn".print_r($_POST, 1)."nn";
$errors .= "---------------------------------------------nn";$errors .= "nnGET:nn".print_r($_GET, 1)."nn";mail("YOUR@EMAIL.COM","PHP Error ".$_SERVER['HTTP_HOST']."", $errors , $head);$fp = fopen($dir."/tiny_uploads/errors.txt","w+");
fputs($fp, "");
fclose($fp);
}
}
}
register_shutdown_function("byebye");
?>
kalle at meizo dot com ¶
13 years ago
This may be of help to someone, who is/was looking for a way to get a backtrace of fatal errors such as maximum memory allocation issues, which can not be handled with user-defined functions, to pin-point the problem:
On a server hosting many sites that share common PHP includes, I set in one spot:
<?php@ini_set ("error_log", "/my/path/php.err-" . $_SERVER ["HTTP_HOST"] . "-" . $_SERVER ["REMOTE_ADDR"] . "-" . $_SERVER ["REQUEST_METHOD"] . "-" . str_replace ("/", "|", $_SERVER ["REQUEST_URI"]));?>
I actually used some additional information too from my software that I omitted, but that way, you'll find errors sorted more neatly in for example:-
/my/path/php.err-website.com-127.0.0.1-GET-path|index.html?xyz
And that at least helped me tremendously to then further pin-point where the problem is, as opposed to before just seeing the out of memory and not knowing which site/page it was on (as the PHP error only contains the very latest PHP code where it ran out of memory, which usually is just a shared included file, not the actual page).
webmaster at paramiliar dot com ¶
15 years ago
We needed to use an error handler to handle SQL errors while passing the query along so the query is also logged and this is what we came up with, its kind of an ugly bridge but it works 100%
<?phpfunction myErrorHandler($errno, $errstr, $errfile, $errline){
switch ($errno) {
case E_USER_ERROR:
if ($errstr == "(SQL)"){
// handling an sql error
echo "<b>SQL Error</b> [$errno] " . SQLMESSAGE . "<br />n";
echo "Query : " . SQLQUERY . "<br />n";
echo "On line " . SQLERRORLINE . " in file " . SQLERRORFILE . " ";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Aborting...<br />n";
} else {
echo "<b>My ERROR</b> [$errno] $errstr<br />n";
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />n";
echo "Aborting...<br />n";
}
exit(1);
break;
case
E_USER_WARNING:
case E_USER_NOTICE:
}
/* Don't execute PHP internal error handler */
return true;
}// function to test the error handlingfunction sqlerrorhandler($ERROR, $QUERY, $PHPFILE, $LINE){
define("SQLQUERY", $QUERY);
define("SQLMESSAGE", $ERROR);
define("SQLERRORLINE", $LINE);
define("SQLERRORFILE", $PHPFILE);
trigger_error("(SQL)", E_USER_ERROR);
}set_error_handler("myErrorHandler");// trigger an sql error
$query = "SELECT * FROM tbl LIMIT 1";
$sql = @mysql_query($query)
or sqlerrorhandler("(".mysql_errno().") ".mysql_error(), $query, $_SERVER['PHP_SELF'], __LINE__);?>
Steffen Staehle ¶
18 years ago
Two notes on using set_error_handler() on behaviour that I noticed when migrating an application from php 4.2.1 to php 4.3.9 (I do not yet have php 5.0 available, this might not apply there!).
1. setting the system error handler
If you want to set the standard php error handler again, after having set your own error handler, this works in php 4.2.1 by passing in an empty string:
<?phpfunction my_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// do something useful
// ...
}$last_handler = set_error_handler("my_handler");// after this, $last_handler == ""
// restore standard error handler
$last_handler = set_error_handler("");// after this, $last_handler == "my_handler"?>
The very same code now raises an error in php 4.3.9:
set_error_handler() expects argument 1, '', to be a valid callback
(Since the return value of the first call to set_error_handler() is still the empty string "", I don't see how this can be done any more. I don't really need this, because I use my own handlers as shown below, but it might be good to be aware of this.)
2. setting your own 'second level' handler
If you have set your own error handler, and want to replace it by another one (other than the standard php error handler) while it is being executed, note that the return value of set_error_handler when used INSIDE the error handler is "" instead of the name of the previous handler! This is not too surprising, because during execution of your self defined error handler, php replaces it with the standard php error handler to avoid infinite loops in case of problems inside the handler. This is only interesting if you want nested handlers as I do. Background of my design:
1st level handler: log into DB
2nd level handler: log into flat file (if log into DB fails)
3rd level handler: print to stdout (if log into flat file fails) (this is the sytem handler, finally).
<?phpfunction my_fallback_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// do something useful
// ...
} // my_fallback_handlerfunction my_handler($log_level, $log_text, $error_file, $error_line)
{
// if an error occurs here, the standard error
// would be called (to avoid recursion)
// but we want to have a fallback handler different
// to the standard error handler
$last_handler = set_error_handler("my_fallback_handler");// I expected $last_handler == "my_handler"
// (which it would outside my_handler())
// but here it is the empty string ""
// do something useful
// ...
// now set the 1st level handler again:
// (do NOT use $last_handler as argument,
// because it equals "")
$last_handler = set_error_handler("my_handler");
}
// my_handler$last_handler = set_error_handler("my_handler");?>
silkensedai at online dot fr ¶
16 years ago
i made an error handler that print also the backtrace and that can die on some errors. It can be useful if you want to die on every error you find.
<?phpfunction my_error_handler($errno, $errstr, $errfile, $errline){
$errno = $errno & error_reporting();
if($errno == 0) return;
if(!defined('E_STRICT')) define('E_STRICT', 2048);
if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096);
print "<pre>n<b>";
switch($errno){
case E_ERROR: print "Error"; break;
case E_WARNING: print "Warning"; break;
case E_PARSE: print "Parse Error"; break;
case E_NOTICE: print "Notice"; break;
case E_CORE_ERROR: print "Core Error"; break;
case E_CORE_WARNING: print "Core Warning"; break;
case E_COMPILE_ERROR: print "Compile Error"; break;
case E_COMPILE_WARNING: print "Compile Warning"; break;
case E_USER_ERROR: print "User Error"; break;
case E_USER_WARNING: print "User Warning"; break;
case E_USER_NOTICE: print "User Notice"; break;
case E_STRICT: print "Strict Notice"; break;
case E_RECOVERABLE_ERROR: print "Recoverable Error"; break;
default: print "Unknown error ($errno)"; break;
}
print ":</b> <i>$errstr</i> in <b>$errfile</b> on line <b>$errline</b>n";
if(function_exists('debug_backtrace')){
//print "backtrace:n";
$backtrace = debug_backtrace();
array_shift($backtrace);
foreach($backtrace as $i=>$l){
print "[$i] in function <b>{$l['class']}{$l['type']}{$l['function']}</b>";
if($l['file']) print " in <b>{$l['file']}</b>";
if($l['line']) print " on line <b>{$l['line']}</b>";
print "n";
}
}
print "n</pre>";
if(isset($GLOBALS['error_fatal'])){
if($GLOBALS['error_fatal'] & $errno) die('fatal');
}
}
function
error_fatal($mask = NULL){
if(!is_null($mask)){
$GLOBALS['error_fatal'] = $mask;
}elseif(!isset($GLOBALS['die_on'])){
$GLOBALS['error_fatal'] = 0;
}
return $GLOBALS['error_fatal'];
}?>
Usage :
<?php
error_reporting(E_ALL); // will report all errors
set_error_handler('my_error_handler');
error_fatal(E_ALL^E_NOTICE); // will die on any error except E_NOTICE
?>
wfinn at riverbed dot com ¶
14 years ago
"The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called."
This is not exactly true. set_error_handler() can't handle them, but ob_start() can handle at least E_ERROR.
<?phpfunction error_handler($output)
{
$error = error_get_last();
$output = "";
foreach ($error as $info => $string)
$output .= "{$info}: {$string}n";
return $output;
}ob_start('error_handler');will_this_undefined_function_raise_an_error();?>
francois vespa ¶
12 years ago
This is a note when using php from the terminal (the CLI interface). From the command line, even if you have some kind of error user handler function so STDERR will not display, fatal errors will still cause the PHP interpreter to display error text. There is nothing you can do about that php-wise. If using UNIX/Linux, you can add " 2>/dev/null" at the end of your command to force STDERR not to show
dorphalsig at NOSPAMgmail dot com ¶
11 years ago
This actually works to catch Fatal errors...
<?phpfunction shutdown()
{
$a=error_get_last();
if(
$a==null)
echo
"No errors";
else
print_r($a);
}
register_shutdown_function('shutdown');ini_set('max_execution_time',1 );sleep(3);?>
it will output
Array ( [type] => 1 [message] => Maximum execution time of 1 second exceeded [file] => /path/to/file_name.php [line] => 136 )
Marcelius ¶
14 years ago
Another way to catch PHP's fatal errors:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
function
shutdown(){
$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if (
$isError){
echo "Script execution halted ({$error['message']})";
} else {
echo "Script completed";
}
}register_shutdown_function('shutdown');
?>
Note that this will only catch runtime errors. So calling a method in a non existing class, or declaring a function twice does not trigger the shutdown handler.
roy ¶
21 years ago
Useful thing to note - if your error handler throws an error in itself, PHP is smart enough to use the deault error handler to handle it. This way, you don't end up in infinite flaming loops of death. This seems to be true, at least, in PHP 4.2.
('Course, there are ways to create your handler to handle even this situation, but it's probably best left this way for general purposes.)
Anonymous ¶
17 years ago
To honor the value of PHP's error_reporting() function, use:
<?
if( ($level & error_reporting()) == 0 ) return;
?>
phpmanual at NO_SPHAMnetebb dot com ¶
19 years ago
Given this code:
class CallbackClass {
function CallbackFunction() {
// refers to $this
}
function StaticFunction() {
// doesn't refer to $this
}
}
function NonClassFunction() {
}
there appear to be 3 ways to set a callback function in PHP (using set_error_handler() as an example):
1: set_error_handler('NonClassFunction');
2: set_error_handler(array('CallbackClass', 'StaticFunction'));
3: $o =& new CallbackClass();
set_error_handler(array($o, 'CallbackFunction'));
The following may also prove useful:
class CallbackClass {
function CallbackClass() {
set_error_handler(array(&$this, 'CallbackFunction')); // the & is important
}
function CallbackFunction() {
// refers to $this
}
}
The documentation is not clear in outlining these three examples.
jtrick77 at gmail dot com ¶
9 years ago
For anyone interested in the actual translated error codes and their meanings:
1 E_ERROR (integer) Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.
2 E_WARNING (integer) Run-time warnings (non-fatal errors). Execution of the script is not halted.
4 E_PARSE (integer) Compile-time parse errors. Parse errors should only be generated by the parser.
8 E_NOTICE (integer) Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
16 E_CORE_ERROR (integer) Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP.
32 E_CORE_WARNING (integer) Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP.
64 E_COMPILE_ERROR (integer) Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.
128 E_COMPILE_WARNING (integer) Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.
256 E_USER_ERROR (integer) User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error().
512 E_USER_WARNING (integer) User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function trigger_error().
1024 E_USER_NOTICE (integer) User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error().
2048 E_STRICT (integer) Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. Since PHP 5 but not included in E_ALL until PHP 5.4.0
4096 E_RECOVERABLE_ERROR (integer) Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR. Since PHP 5.2.0
8192 E_DEPRECATED (integer) Run-time notices. Enable this to receive warnings about code that will not work in future versions. Since PHP 5.3.0
16384 E_USER_DEPRECATED (integer) User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error(). Since PHP 5.3.0
32767 E_ALL (integer) All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0. 32767 in PHP 5.4.x, 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously
(Copied from http://php.net/manual/en/errorfunc.constants.php)
nicolas dot grekas+php at gmail dot com ¶
9 years ago
If you want to be sure that the native PHP error handler is called without resetting the handler stack (as set_error_handler(null) does), you can simply call set_error_handler with $error_types set to zero. This can be especially use full in conjunction with e.g. error_get_last():
<?php// var_dump or anything else, as this will never be called because of the 0
set_error_handler('var_dump', 0);
@$undef_var;
restore_error_handler();// error_get_last() is now in a well known state:
// Undefined variable: undef_var... // Do something$e = error_get_last();
...
?>
phil at propcom dot co dot uk ¶
9 years ago
It is important to note that the registered SPL autoloader will NOT be called if an E_STRICT error triggers the error handler which, in turn, tries to use classes which are not yet loaded.
In this instance, you should manually load classes required by the error handler.
stepheneliotdewey at GmailDotCom ¶
16 years ago
The manual states:
"errcontext will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context."
But do you know WHY you must not modify the error context? It appears that errcontext is (in effect if not literally) created by taking $GLOBALS and adding the non-global local variables as additional entries in that array, then passing the whole thing *by reference*.
(You can prove this to be true if you set up a custom error handler and then print_r($errcontext) within it, because $GLOBALS will be printed as a recursive array).
In other words, the language in the manual is misleading, because errcontext is NOT a copy of the variables that existed when the error WAS triggered, but rather is a reference to the *existing LIVE variables* in the calling script.
This includes superglobal variables like $_SERVER, $_POST, $_GET, etc., as well as all user-defined variables in scope.
The significance of that is that if you modify errcontext, you will be modifying those other variables, not just for the life of your error handling function, but for the life of the calling script as well.
That doesn't matter if you plan to halt execution in your error handling function, but it will lead to unexpected behavior if you modify $errcontext and then return to the program's normal flow after handling the error, because the variables will stay modified. For example, if you unset $_SERVER in your custom error handling function, it will remain unset once the function is over and you have returned to the page that generated the error.
This should be made clearer in the manual, starting by marking errhandler with an ampersand (&) for passage by reference in the "Parameters" section above, like so:
handler ( int $errno, string $errstr [, string $errfile [, int $errline [, array &$errcontext]]] )
Anonymous ¶
19 years ago
It seems that when you're letting PHP know that you have a custom error handler, you're not able to -update/set new- variables inside the class. Example:
<?phpclass error {
var
$error;
function
error() {$this->setIni(); // this causes PHP to ignore all other changes to the class.}
function
handler() {
echo
$this->error.'!!';
}
function
setText($text) {$this->error = $text;
}
function
setIni() {set_error_handler(array($this, 'handler'));
}
}
$eh = new error;$eh->setText('Error! <br>'); // this will not be saved
trigger_error('text', E_USER_ERROR);// prints '!!'?>
How it should be done:
<?phpclass error {
var
$error;
function
error() {// dont let PHP know of our error handler yet}
function
handler() {
echo
$this->error.'!!';
}
function
setText($text) {$this->error = $text;
}
function
setIni() {set_error_handler(array($this, 'handler'));
}
}
$eh = new error;$eh->setText('Error! <br>'); // this WILL work$eh->setIni(); // call this method when you're ready with configuring the class. All other methods that will be called will have no effect on the errorHandling by PHP
trigger_error('text', E_USER_ERROR);// prints 'Error! <br>!!'?>
periklis ¶
12 years ago
How to handle fatal errors in php 5.2:
<?php
register_shutdown_function
('shutdownFunction');
function
shutDownFunction() {$error = error_get_last();
if (
$error['type'] == 1) {//do your stuff }
}
?>
Klauss ¶
5 years ago
Hi everyone. I don't know if it is an old behavior of previous versions, but currently you can set exception and error handlers as private or protected methos, if, only if, you call `set_exception_handler()` or `set_error_handler()` within a context that can access the method.
Example:
<?PHP
$Handler = new class ()
{
public function __construct ()
{
set_error_handler([&$this, 'HandleError']);
set_exception_handler([&$this, 'HandleException']);
}
protected function HandleError ( $Code, $Message, $File = null, $Line = 0, $Context = [] )
{
// Handle error here.
}
private function HandleException ( $Exception )
{
// Handle exception here.
}
}
?>
NOTE: these methods must match the callbacks parameters signatures.
RGraph ¶
4 months ago
A simple error handler that makes errors far more visible:
//
// Set the error handler to one that prints out more
// visible errors
//
set_error_handler(function ($errno, $errstr)
{
$str = '<div style="margin: 20px; background-color: #fdd; border: 3px solid red; padding: 10px; border-radius: 15px; line-height: 25px"><b>Error: </b>%s (error level: %s)</div>';
printf($str, $errstr, $errno);
});
a dot ross at amdev dot eu ¶
4 years ago
I'm missing a way to chain error handlers. It's not something offered by set_error_handler. You have to jump through some hoops to get it to work, but it *is* quite possible, by making use of the return value of the function. Here's an example:
<?
$previous = set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$previous) {
/* Your custom error handling code here. */
// If another error handler was defined, call it.
if ($previous) {
return $previous($errno, $errstr, $errfile, $errline, $errcontext);
} else {
// Use the standard PHP error handler.
return false;
}
});
?>
kaioker ¶
1 year ago
super simple error code to human readable conversion:
function prettycode($code){
return $code == 0 ? "FATAL" : array_search($code, get_defined_constants(true)['Core']);
}
Alex M ¶
2 years ago
If you are new to programming and you would like to know how to add a combination of those error reporting values to .htaccess file. Here's a small guide.
With PHP function error_reporting we can add together option with bitwise add operator | . But we can't use those constants in htaccess file and in my case I have no idea how to add bitwise number.
So, solution can be casting selected options to int:
echo (int)(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR) ;
->263
Then you can use 263 in .htaccess
php_value error_reporting 263
In my case I needed those errors to be displayed for my debugging server. But the combination can be different from mine.
David Spector ¶
2 years ago
The PHP manual is not very clear about how to handle @ operator error messages.
Here is working code:
// Do nothing if @ operator
$errLevel=error_reporting(E_ALL);
if ($errLevel===0)
return true; // ignore @ prefixed expression errors
chris at ocproducts dot com ¶
6 years ago
Note that error handlers don't run recursively. If you have an error while an error handler is running (in the error handler itself or code called from it) then you won't get the error handler called again.
This has subtle ramifications for $php_errormsg. If you are relying on your error handler to suppress certain kinds of error message from going into $php_errormsg (via return true; because error_reporting doesn't affect $php_errormsg setting) then this will not work for any code called within that error handler.
devermin at ti0n dot net ¶
13 years ago
At work I have some code with errors that uncatched are the causes of integrity loss (people calling web services with file_get_contents that fails silently and afterwards insert garbage in the database).
here is the solution I found to transform a specific set of errors into exception and afterwards be able to selectively act (with the error code) regarding categories :
<?php
ini_set
('error_reporting',E_ALL^E_NOTICE);
## first 10 bits reserved for the initial error numberdefine('EMASK',(~0)<<10);define('ECODEMASK',~EMASK);## categoriesdefine('IOERROR', 1<<10);define('EMPTYPARMS', 1<<11);define('FAILURE', 1<<12);## string error patterns => code
$catch_me=array("/^(file_get_contents)((.*)).*failed to open stream: (.*)/ " =>
array (
'mesg' => "IO::Failed to open stream with",'code' => IOERROR | FAILURE),"/^fopen(.*): Filename cannot be empty/" =>
array(
'msg' => "Parameters::empty",'code' => EMPTYPARMS)
);
function
error_2_exception($errno, $errstr, $errfile, $errline,$context) {
global
$catch_me;
foreach (
$catch_me as $regexp => $res) {
if(
preg_match($regexp,$errstr,$match)){
throw new
Exception($res['mesg'],$res['code']|( $errno & EMASK ) );
}
}
/* switch back to PHP internal error handler */return false;
}
## => want to catch this one$f=file_get_contents("mlsdkfm");## dont want to break existing wrong behaviour yet (so not caught)$f=file_get_contents('');## magicset_error_handler("error_2_exception");## behaviour remains the same$f=file_get_contents('');
try {
## web services that dont work now raise an exception o/$f=file_get_contents("mlsdkfm");
} catch(
Exception $e) {## and I can group my exception by categoryecho ( $e->getCode() & FAILURE ) ? "nEPIC FAILn" : "nbegnine";
}
?>
ash ¶
15 years ago
error handling function that handles both errors and exceptions; also features a backtrace including possible function arguments.
<?php
$cfg
= array();
$cfg['debug'] = 1;
$cfg['adminEmail'] = 'name@domain.tld';
function
errorHandler($errno, $errstr='', $errfile='', $errline='')
{
// if error has been supressed with an @
if (error_reporting() == 0) {
return;
}
global
$cfg;// check if function has been called by an exception
if(func_num_args() == 5) {
// called by trigger_error()
$exception = null;
list($errno, $errstr, $errfile, $errline) = func_get_args();$backtrace = array_reverse(debug_backtrace());
}else {
// caught exception
$exc = func_get_arg(0);
$errno = $exc->getCode();
$errstr = $exc->getMessage();
$errfile = $exc->getFile();
$errline = $exc->getLine();$backtrace = $exc->getTrace();
}$errorType = array (
E_ERROR => 'ERROR',
E_WARNING => 'WARNING',
E_PARSE => 'PARSING ERROR',
E_NOTICE => 'NOTICE',
E_CORE_ERROR => 'CORE ERROR',
E_CORE_WARNING => 'CORE WARNING',
E_COMPILE_ERROR => 'COMPILE ERROR',
E_COMPILE_WARNING => 'COMPILE WARNING',
E_USER_ERROR => 'USER ERROR',
E_USER_WARNING => 'USER WARNING',
E_USER_NOTICE => 'USER NOTICE',
E_STRICT => 'STRICT NOTICE',
E_RECOVERABLE_ERROR => 'RECOVERABLE ERROR'
);// create error message
if (array_key_exists($errno, $errorType)) {
$err = $errorType[$errno];
} else {
$err = 'CAUGHT EXCEPTION';
}$errMsg = "$err: $errstr in $errfile on line $errline";// start backtrace
foreach ($backtrace as $v) {
if (isset(
$v['class'])) {$trace = 'in class '.$v['class'].'::'.$v['function'].'(';
if (isset(
$v['args'])) {
$separator = '';
foreach(
$v['args'] as $arg ) {
$trace .= "$separator".getArgument($arg);
$separator = ', ';
}
}
$trace .= ')';
}
elseif (isset(
$v['function']) && empty($trace)) {
$trace = 'in function '.$v['function'].'(';
if (!empty($v['args'])) {$separator = '';
foreach(
$v['args'] as $arg ) {
$trace .= "$separator".getArgument($arg);
$separator = ', ';
}
}
$trace .= ')';
}
}// display error msg, if debug is enabled
if($cfg['debug'] == 1) {
echo '<h2>Debug Msg</h2>'.nl2br($errMsg).'<br />
Trace: '.nl2br($trace).'<br />';
}// what to do
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
return;
break;
default:
if(
$cfg['debug'] == 0){
// send email to admin
if(!empty($cfg['adminEmail'])) {
@mail($cfg['adminEmail'],'critical error on '.$_SERVER['HTTP_HOST'], $errorText,
'From: Error Handler');
}
// end and display error msg
exit(displayClientMessage());
}
else
exit('<p>aborting.</p>');
break;
}
}
// end of errorHandler()function displayClientMessage()
{
echo 'some html page with error message';
}
function
getArgument($arg)
{
switch (strtolower(gettype($arg))) {
case
'string':
return( '"'.str_replace( array("n"), array(''), $arg ).'"' );
case
'boolean':
return (bool)$arg;
case
'object':
return 'object('.get_class($arg).')';
case
'array':
$ret = 'array(';
$separtor = '';
foreach (
$arg as $k => $v) {
$ret .= $separtor.getArgument($k).' => '.getArgument($v);
$separtor = ', ';
}
$ret .= ')';
return
$ret;
case
'resource':
return 'resource('.get_resource_type($arg).')';
default:
return
var_export($arg, true);
}
}?>
mmtache at yahoo dot com ¶
20 years ago
The @ operator sets the error_reporting() value to 0.
This means you can use it with your own Error Handler too. for example:
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
if (error_reporting())
echo $errmsg;
}
set_error_handler("userErrorHandler");
function test(){
trigger_error("Error Message", E_USER_WARNING);
}
@test(); // doesn't output anything
Материал из Справочник Web-языков
Перейти к: навигация, поиск
set_error_handler
Установка пользовательского обработчика ошибок.
Синтаксис:
string set_error_handler(string error_handler)
Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в качестве нового обработчика, функцию с указанным в аргументе error_handler именем.
Обычно пользовательский обработчик ошибок работает в паре с функцией trigger_error(), генерирующей ошибку. Это может быть использовано (подобно аналогичной конструкции работы с исключениями в C) для освобождения выделенных ресурсов (например, удаления созданных файлов), если сценарий не может нормально завершиться.
Функция, устанавливаемая в качестве обработчика ошибок, должна принимать пять параметров (три последних являются дополнительными и могут не обрабатываться):
- код ошибки
- строку, описывающую ошибку
- имя сценария, в котором произошла ошибка
- номер строки сценария, содержащей ошибку
- контекст (массив, содержащий значения переменных, в момент возникновения ошибки)
<?php // определить константы пользовательских ошибок define(FATAL, E_USER_ERROR); define(ERROR, E_USER_WARNING); define(WARNING, E_USER_NOTICE); // установить, какие ошибки должны обрабатываться в сценарии error_reporting (FATAL | ERROR | WARNING); // пользовательский обработчик ошибок function myErrorHandler($errno,$errstr,$errfile,$errline) { switch ($errno) { case FATAL: echo "Критическая ошибка [$errno] $errstr
n"; echo "в строке: $errline файла:".$errfile; echo ", PHP ".PHP_VERSION." (".PHP_OS.")
n"; echo "Aborting...
n"; exit -1; break; case ERROR: echo "Ошибка [$errno] $errstr
n"; break; case WARNING: echo "Предупреждение [$errno] $errstr
n"; break; default: echo "Неизвестный тип ошибки: [$errno] $errstr
n"; } } // функция для проверки обработки ошибок // (масштабирование массива function scale_by_log($vect, $scale) { if(!is_numeric($scale) || $scaleПри выполнении сценария вывод будет следующим:
Array ( [0] => 2 [1] => 3 [2] => foo [3] => 5.5 [4] => 43.3 [5] => 21.11 ) Предупреждение [1024] Элемент (2) не число, и его значением считается 0<br> Массив, масштабированный на логарифм(Пи): Array ( [0] => 2.2894597716988 [1] => 3.4341896575482 [2] => 0 [3] => 6.2960143721717 [4] => 49.566804057279 [5] => 24.165247890281 ) <b>Ошибка</b> [512] Требуется массив <br> NULL <b>Критическая ошибка</b> [256] вычислить log(x) для x <=0 нельзя, (x = -2.5)<br> в строке: 37, файла E:wwwexampl.php, PHP 4.0.5 (WINNT)<br> Aborting...<br>Не забывайте, что при установке пользовательского обработчика ошибок стандартный обработчик PHP не используется. Установки error_reporting() также не будут иметь эффекта, и пользовательский обработчик должен уметь обрабатывать все виды ошибок (значение error_reporting() можно выяснить и действовать соотвественно). Заметьте, что код ошибки будет равен 0, если ошибка возникла в функции, вывод ошибок для которой был блокирован оператором "@".
Также помните, что завершать сценарий в обработчике необходимо явно (например, с помощью функции die(), если, конечно, в этом есть необходимость. Если обработчик ошибок завершается с помощью return, то выполнение сценария продолжается с того места, в котором возникла ошибка (то есть исполняются инструкции, которые следуют за той инструкцией, в которой возникла ошибка).
Ссылки
- Собственная страница обработки ошибок в скриптах
PHP5 Обработка ошибок
Обработка ошибок по умолчанию в PHP очень проста. Сообщение об ошибке с именем файла, строка число и сообщение, описывающее ошибку, отправляется в браузер.
При создании скриптов и веб-приложений, обработка ошибок, является важной
частью. Если коду не хватает кода проверки ошибок, программа может выглядеть
непрофессионально и Вы можете быть открыты для рисков безопасности.
Учебник содержит несколько из наиболее распространенных методов проверки ошибок в PHP.
Вы узнаете различные методы обработки ошибок:
- Простое заявление
это()
- Пользовательские ошибки и триггеры ошибок
- Отчеты об ошибках
PHP Основная обработка ошибок
В первом примере показан простой скрипт, открывающий текстовый файл: использование функции это()
Пример
<?php
$file=fopen(«welcome.txt»,»r»);
?>
Если файл не существует, Вы можете получить ошибку, как эта:
Внимание: fopen(welcome.txt) [function.fopen]: не удалось открыть поток:
Нет такого файла или каталога в C:\webfolder\test.php на линии 2
Чтобы запретить пользователю получать сообщение об ошибке, подобное приведенному примеру выше, мы проверяем
файл, существует ли он до того, как мы попытаемся получить к нему доступ:
Пример
<?php
if(!file_exists(«welcome.txt»)) {
die(«Файл не найден»);
}
else {
$file=fopen(«welcome.txt»,»r»);
}
?>
Теперь, если файл не существует вы получите ошибку, как эта:
Файл не найден
Приведенный ниже код более эффективен, чем предыдущий код, поскольку он использует простой механизм обработки ошибок для остановки сценария после ошибки.
Тем не менее, остановить просто сценарий не всегда правильный путь. Рассмотрим альтернативные функции PHP для обработки ошибок.
PHP Создание пользовательского обработчика ошибок
Создать пользовательский обработчик ошибок довольно просто. Создаем специальную функцию, которая может быть вызвана при возникновении ошибки в PHP.
Эта функция должна быть способна обрабатывать, как минимум два параметра (уровень ошибки и сообщение об ошибке),
но можно принимать до пяти параметров (дополнительно: файл, номер строки и контекст ошибки):
Синтаксис
error_function(error_level,error_message,
error_file,error_line,error_context)
Параметр | Описание |
---|---|
error_level | Необходимо. Указывает уровень отчета об ошибках для пользовательской ошибки. Должно быть числовое значение. См. таблицу ниже для возможных уровней отчета об ошибках |
error_message | Необходимо. Указывает сообщение об ошибке определяемая пользователем |
error_file | Необязательно. Задает имя файла, в котором произошла ошибка |
error_line | Необязательно. Указывает номер строки, в которой произошла ошибка |
error_context | Необязательно. Задает массив, содержащий все переменные и их значения, используемые при возникновении ошибки |
PHP Уровни отчетов об ошибках
Эти уровни отчетов об ошибках, являются различными типами ошибок, для которых может использоваться определяемый пользователем обработчик ошибок:
Значение | Констант | Описание |
---|---|---|
2 | E_WARNING | Неустранимые ошибки выполнения. Выполнение скрипта не останавливается |
8 | E_NOTICE | Уведомления среды выполнения. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария, как обычно |
256 | E_USER_ERROR | Неустранимая ошибка пользователя. Это похоже на набор E_ERROR установленный программистом с помощью функции PHP trigger_error() |
512 | E_USER_WARNING | Неустранимое пользовательское предупреждение. Это похоже на набор E_WARNING установленный программистом с помощью функции PHP trigger_error() |
1024 | E_USER_NOTICE | Автоматическое уведомление пользователя. Это похоже на набор E_NOTICE устанавливается программистом с помощью функции PHP trigger_error() |
4096 | E_RECOVERABLE_ERROR | Перехватываемая неустранимая ошибка. Это похоже на набор E_ERROR но может быть перехватана пользователем, определенной обработкой (смотреть также set_error_handler()) |
8191 | E_ALL | Все ошибки и предупреждение (E_STRICT становится частью E_ALL в PHP 5.4) |
Теперь давайте создадим функцию для обработки ошибок:
Пример
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Конечный Script»;
die();
}
Приведенный выше код, является простой функцией обработки ошибок. Когда он срабатывает, он получает код ошибки и сообщение об ошибке.
Затем выводится уровень ошибки и сообщение и завершается сценарий.
Теперь, когда Вы создали функцию обработки ошибок, Вы должны решить, когда она должно сработать.
PHP Установить обработчик ошибок
Обработчик ошибок по умолчанию для PHP является встроенным обработчиком ошибок.
Мы собираемся сделать функцию над обработчиком ошибок по умолчанию на время скрипта.
Можно изменить обработчик ошибок для применения только к некоторым ошибкам, таким образом,
сценарий может обрабатывать различные ошибки по-разному.
Однако, в этом примере мы будем использовать наш пользовательский обработчик ошибок для всех ошибок:
set_error_handler(«customError»);
Поскольку мы хотим, чтобы наша пользовательская функция обрабатывала все ошибки, set_error_handler()
требуется только один параметр, второй параметр может быть добавлен, чтобы указать уровень ошибки.
Тестирование обработчика ошибок при попытке вывести несуществующую переменную:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr»;
}
//установить обработчик ошибок
set_error_handler(«customError»);
//Вызов ошибки
echo($test);
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [8] Неопределенна переменная: test
PHP Вызвать ошибку
В скрипте, где пользователи могут вводить данные, полезно инициировать ошибки, когда происходит незаконный ввод.
В PHP это делается с помощью функции trigger_error()
.
В этом примере возникает ошибка, если $test
переменная больше, чем 1
:
Пример
<?php
$test=2;
if ($test>=1)
{
trigger_error(«Значение должно быть 1 или ниже»);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Заметьте: Значение должно быть 1 или ниже
в C:\webfolder\test.php на линии 6
Ошибка может быть вызвана в любом месте сценария и путем добавления
второй параметр, Вы можете указать, какой уровень ошибки срабатывает.
Возможные типы ошибок:
- E_USER_ERROR — Неустранимая пользовательская ошибка выполнения. Ошибки, из которых невозможно восстановить. Выполнение скрипта прекращается
- E_USER_WARNING — Непоправимое пользовательское предупреждение во время выполнения. Выполнение скрипта не останавливается
- E_USER_NOTICE — Невыполнение. Уведомление о времени выполнения, созданное пользователем. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария
В этом примере E_USER_WARNING происходит, если переменная $test
больше, чем 1
. Если происходит E_USER_WARNING мы будем использовать наш пользовательский обработчик ошибок и закончить сценарий:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Закончить Script»;
die();
}
//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);
//вызов ошибки
$test=2;
if ($test>=1) {
trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [512] Значение должно быть 1 или ниже
Конец скрипта
Теперь, когда мы научились создавать собственные ошибки и как их вызвать,
давайте посмотрим на ошибки.
PHP Регистрация ошибок
По умолчанию, PHP отправляет отчет об ошибке в систему регистрации на сервер или файл,
в зависимости от того, как конфигурация error_log установлена в php.ini-файл. По
с помощью функции error_log()
можно отправлять журнал ошибок в указанный файл или в удаленное место назначения.
Отправка сообщений об ошибках по электронной почте, может быть хорошим способом получения уведомления о конкретных ошибках.
PHP Отправка сообщение об ошибке по электронной почте
В приведенном ниже примере мы отправим электронное письмо с сообщением об ошибке и
сценарий, если возникает ошибка:
Пример
<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
echo «Веб-мастер был уведомлен»;
error_log(«Ошибка: [$errno] $errstr»,1,
«someone@example.com»,»От: webmaster@example.com»);
}
//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);
//вызов ошибки
$test=2;
if ($test>=1) {
trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>
Выходные данные приведенного выше кода должны быть примерно такими:
Ошибка: [512] Значение должно быть 1 или ниже
Веб-мастер был уведомлен
И почта, полученная из кода выше, выглядит так:
Ошибка: [512] начение должно быть 1 или ниже
Не должно использоваться со всеми ошибками. Регулярные ошибки должны быть зарегистрированы на
сервере, использующий систему регистрации PHP по умолчанию.
Обработка ошибок — это процесс обнаружения ошибок, вызванных вашей программой, а затем принятия соответствующих мер. Если вы будете правильно обрабатывать ошибки, это может привести ко многим непредвиденным последствиям.
Содержание:
- Использование функции die()
- Определение пользовательской функции обработки ошибок
- Возможные уровни ошибок
- Обработка исключений
- Создание настраиваемого обработчика исключений
Это очень просто в PHP для обработки ошибок.
Использование функции die()
При написании вашей программы PHP вы должны проверить все возможные условия ошибки перед тем, как идти вперед, и при необходимости предпринять соответствующие действия.
Попробуйте привести пример без файла / tmp / test.xt и с этим файлом.
<?php if(!file_exists ("/ tmp /test.txt")) { die("File not found"); } else { $file = fopen("/ tmp / test.txt" , "r " ); print "Opend file sucessfully"; } // Test of the code here. ?>
Таким образом, вы можете написать эффективный код. Используя вышеприведенную технику, вы можете остановить свою программу всякий раз, когда она выдает ошибки и отображает более содержательные и удобные для пользователя сообщения.
Определение пользовательской функции обработки ошибок
Вы можете написать свою собственную функцию для обработки любой ошибки. PHP предоставляет вам структуру для определения функции обработки ошибок.
Эта функция должна иметь возможность обрабатывать минимум два параметра (уровень ошибки и сообщение об ошибке), но может принимать до пяти параметров (опционально: файл, номер строки и контекст ошибки) —
Синтаксис
error_function(error_level,error_message, error_file,error_line,error_context);
# | Параметр | Описание |
---|---|---|
1 | error_level | Обязательный параметр — задает уровень отчета об ошибке для пользовательской ошибки. Значение должно быть числом. |
2 | error_message | Обязательный параметр — указывает сообщение об ошибке для пользовательской ошибки |
3 | error_file | Необязательный. Указывает имя файла, в котором произошла ошибка. |
4 | error_line | Необязательный. Указывает номер строки, в которой произошла ошибка. |
5 | error_context | Необязательный. Указывает массив, содержащий каждую переменную, и их значения, используемые при возникновении ошибки. |
Возможные уровни ошибок
Эти уровни отчетов об ошибках представляют собой различные типы ошибок, к которым может использоваться пользовательский обработчик ошибок. Эти значения используются в комбинации с использованием | оператор
# | Константа | Описание | Значение |
---|---|---|---|
1 | .E_ERROR | Неустранимая ошибки во время выполнения. Выполнение сценария останавливается | 1 |
2 | E_WARNING | Нефатальные ошибки во время выполнения. Выполнение скрипта не останавливается | 2 |
3 | E_PARSE | Ошибки анализа времени компиляции. Ошибки анализа должны генерироваться только парсером. | 4 |
4 | E_NOTICE | Уведомления о времени выполнения. Скрипт нашел что-то, что может быть ошибкой, но может также произойти при обычном сценарии | 8 |
5 | E_CORE_ERROR | Неустранимая ошибки, возникающие во время первоначального запуска PHP. | 16 |
6 | E_CORE_WARNING | Нефатальные ошибки во время выполнения. Это происходит во время первоначального запуска PHP. | 32 |
7 | E_USER_ERROR | Неустранимая пользовательская ошибка. Это похоже на набор E_ERROR программиста, использующий функцию PHP trigger_error() | 256 |
8 | E_USER_WARNING | Нефатальное пользовательское предупреждение. Это похоже на E_WARNING, установленный программистом с использованием функции PHP trigger_error() | 512 |
9 | E_USER_NOTICE | Пользовательское уведомление. Это похоже на набор E_NOTICE, заданный программистом с использованием функции PHP trigger_error() | 1024 |
10 | E_STRICT | Уведомления о времени выполнения. Включите, чтобы PHP предлагал изменения в вашем коде, что обеспечит лучшую совместимость и передовую совместимость вашего кода. | 2048 |
11 | E_RECOVERABLE_ERROR | Ловкая ошибка. Это похоже на E_ERROR, но может быть захвачен определяемым пользователем дескриптором (см. Также set_error_handler()) | 4096 |
12 | E_ALL | Все ошибки и предупреждения, кроме уровня E_STRICT(E_STRICT будет частью E_ALL с PHP 6.0) | 8191 |
Все указанные выше уровни ошибок можно задать, используя встроенную библиотечную функцию PHP, где уровень ошибки будет любым значением, определенным в таблице выше.
int error_reporting ([ int $ level])
Ниже приведен способ создания одной функции обработки ошибок —
<?php function handleError($errno, $errstr,$error_file,$error_line) { echo "<b>Error:</b> [$errno] $errstr - $error_file:$error_line"; echo " "; echo "Terminating PHP Script"; die(); } ?>
После того, как вы определили свой собственный обработчик ошибок, вам нужно установить его с помощью встроенной библиотеки set_error_handler. Теперь давайте рассмотрим пример, вызвав функцию, которая не существует.
<?php error_reporting( E_ERROR ); function handleError($errno, $errstr,$error_file,$error_line) { echo "<b>Error:</b> [$errno] $errstr - $error_file:$error_line"; echo " "; echo "Terminating PHP Script"; die(); } //set error handler set_error_handler("handleError"); //trigger error myFunction(); ?>
Обработка исключений
PHP 5 имеет модель исключения, аналогичную модели других языков программирования. Исключения важны и обеспечивают лучший контроль над обработкой ошибок. Позволяет объяснить там новое ключевое словосвязанное с исключениями.
- Try — функция, использующая исключение, должна находиться в блоке «try». Если исключение не запускается, код будет продолжен как обычно. Однако, если исключение инициируется, исключение «бросается».
- Throw — это то , как вы вызываете исключение. Каждый «бросок» должен иметь хотя бы один «улов».
- Catch. Блок «catch» извлекает исключение и создает объект, содержащий информацию об исключении.
- Когда генерируется исключение, код, следующий за оператором, не будет выполнен, а PHP попытается найти первый соответствующий блок catch. Если исключение не поймано, PHP Fatal Error будет выпущена с помощью «Uncaught Exception …»
- Исключение может быть выброшено, и поймал ( « пойманный ») в PHP. Код может быть окружен в блоке try.
- Каждая попытка должна иметь по крайней мере один соответствующий блок catch. Для блокировки различных классов исключений можно использовать несколько блоков catch.
- Исключения могут быть сброшены (или повторно выбраны) в блоке catch.
пример
Ниже приведен фрагмент кода, скопируйте и вставьте этот код в файл и проверьте результат.
<?php try { $error = 'Always throw this error'; throw new Exception($error); // Code following an exception is not executed. echo 'Never executed'; }catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } // Continue execution echo 'Hello World'; ?>
В приведенном выше примере функция $e->getMessage
используется для получения сообщения об ошибке. Существуют следующие функции, которые могут использоваться из класса Exception.
- GetMessage() — сообщение об исключении
- GetCode() — код исключения
- GetFile() — исходное имя файла
- GetLine() — исходная строка
- GetTrace() — n массив backtrace()
- GetTraceAsString() — сформированная строка трассировки
Создание настраиваемого обработчика исключений
Вы можете определить собственный собственный обработчик исключений. Используйте следующую функцию для установки пользовательской функции обработчика исключений.
string set_exception_handler(callback $exception_handler)
Здесь exception_handler — это имя вызываемой функции, когда происходит неперехваченное исключение. Эта функция должна быть определена перед вызовом set_exception_handler().
пример
<?php function exception_handler($exception) { echo "Uncaught exception: " , $exception->getMessage(), "\n"; } set_exception_handler('exception_handler'); throw new Exception('Uncaught Exception'); echo "Not Executed\n"; ?>
С уважением, авторы сайта Компьютерапия
Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!
•MX (по умолчанию)
•NS
•SOA
•PTR
•CNAME
•ANY
Аргумент host может указываться строкой в формате IP с разделением точками, либо быть именем хоста.
getmxrr
Производит получение MX записи для интернет-хоста.
Синтаксис :
int getmxrr(string hostname, array mxhosts [, array weight]);
Функция getmxrr() инициирует поиск в базе данных DNS записи MX (почтовый сервер домена) для хоста hostname.
Если запись найдена, возвращает true, если нет — то false.
Список записей MX заносится в массив mxhosts. Если указан массив weight, он заполняется дополнительной информацией о записях.
Отслеживание и обработка ошибок : Введение
PHP имеет следующие типы ошибок и предупреждений:
Значение |
Константа |
Описание |
|||
1 |
E_ERROR |
Фатальная ошибка времени исполнения. |
|||
2 |
E_WARNING |
Предупреждение времени исполнения. |
|||
4 |
E_PARSE |
Сообщение интерпретации времени |
|||
исполнения. |
|||||
8 |
E_NOTICE |
Простое сообщение времени исполнения. |
|||
16 |
E_CORE_ERROR |
Фатальная ошибка при инициализации PHP. |
|||
32 |
E_CORE_WARNING |
Предупреждение инициализации. |
|||
64 |
E_COMPILE_ERROR |
Фатальная ошибка компиляции. |
|||
128 |
E_COMPILE_WARNING Предупреждение компиляции. |
||||
256 |
E_USER_ERROR |
Ошибки, определяемые пользователем. |
|||
512 |
E_USER_WARNING |
Предупреждения, определяемые |
|||
пользователем. |
|||||
1024 |
E_USER_NOTICE |
Сообщения, определяемые пользователем. |
|||
2047 |
E_ALL |
Все перечисленные сообщения. |
|||
Указанные значения в виде чисел или констант можно комбинировать, формируя битовую маску ошибок, о которых необходимо сообщать в ходе исполнения сценария. Для комбинирования используются битовые операторы, но в конфигурационном файле php.ini распознаются только «|», «~», «!» и «&».
В PHP 4 по умолчанию разрешены сообщения вида E_ALL & ~E_NOTICE, то есть
сообщаться должно все, кроме обычных сообщений. Можно переопределить эту установку параметром файла конфигурации error_reporting() (ее также можно указывать в файлах конфигурации сервера Apache).
Если при вызове функции перед ее именем указать символ «@», то в случае возникновения ошибки в этой функции сообщение о нем выдаваться не будет.
В настоящее время оператор игнорирования ошибок блокирует даже выдачу сообщений о критических ошибках, при возникновении которых сценарий досрочно завершается.
Если разрешен параметр конфигурации track_errors, то сообщение об ошибке сохраняется в глобальной переменной $php_errormsg.
<?
// определенный пользователем обработчик ошибок
function userErrorHandler($errno,$errmsg,$filename,$linenum,$vars) { // время возникновения ошибки
$dt=date(«Y-m-d H:i:s (T)»); $errortype = array(
1=> «Error»,
2=> «Warning»,
4 => «Parsing Error»,
8 => «Notice»,
16 => «Core Error»,
32 => «Core Warning»,
64 => «Compile Error»,
128 => «Compile Warning»,
256 => «User Error»,
512 => «User Warning»,
1024 => «User Notice» );
$err.=»время ($dt), номер ошибки ($errno), «; $err.=»тип ошибки («.$errortype[$errno].»): «; $err.=»\»$errmsg\».файл \»$filename\», строка («; $err.=$linenum.»)\n»;
$user_errors=array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); if(in_array($errno, $user_errors))
//выдать сообщение для ошибок пользователя echo $err;
//сохранить событие ошибки в системном журнале error_log($err, 3, «/usr/local/php4/error.log»);
}
//установить уровень контроля ошибок и обработчик error_reporting(0); // не выводить сообщения PHP $old_error_handler=set_error_handler(«userErrorHAndler»);
//неопределенная константа вызывает предупреждение
$t=_NOT_DEFINED_CONSTANT;
trigger_error(«Моя ошибка», E_USER_ERROR); trigger_error(«Мое предупреждение», E_USER_WARNING);
?>
Отслеживание и обработка ошибок : Функции обработки ошибок
error_log
Посылка сообщения об ошибке.
Синтаксис :
int error_log(string message, int message_type [, string destination [, string extra_headers]])
Сообщение, посылаемое этой функцией, может быть направлено в журнал системных сообщений web-сервера, прот TCP или в файл.
В первом аргументе message указывается само содержание сообщения. Во втором аргументе message_type — куда оно должно быть направлено.
Назначение обозначается следующими значениями:
•0 — Сообщение заносится в системный журнал событий (файл) согласно установке параметра конфигурации error_log.
•1 — Сообщение отправляется по электронной почте, по адресу, указанному в аргументе destination. Это единственный тип сообщения, использующий четвертый параметр extra_headers, в котором можно указать дополнительные заголовки (как в функции mail()).
•2 — Сообщение посылается через подключение отладки. Это возможно только в случае, если параметр удаленной отладки был разрешен в файле конфигурации. Для этого также должен быть определен адрес хоста (имя или его IP адрес) и порт сокета, который будет принимать сообщения отладки. Это можно указать в аргументе destination или параметрах конфигурации.
•3 — message добавляется в конец файла destination.
if(!Ora_London($username, $password)) { error_log(«Сервер Oracle недоступен!», 0);
};
if(!($foo = allocate_new_foo()) {
error_log(«Нельзя выделить FOO!», 1, «operator@mydomain.ru»);
}
// other ways of calling error_log(): error_log(«У нас ошибка!», 2, «127.0.0.1:7000»); error_log(«У нас ошибка!», 2, «localhost»);
error_log(«У нас ошибка!», 3, «/var/tmp/my-errors.log»);
error_reporting
Установка видов сообщаемых ошибок.
Синтаксис :
int error_reporting([int level])
Функция error_reporting() возвращает предыдущую установку типа сообщаемых ошибок. Если указан аргумент, то заново переопределяет ее. В аргументе можно указывать константу, число или битовую маску. Старайтесь использовать константы вместо численных значений, чтобы сохранить совместимость с будущими версиями PHP.
error_reporting(2039); // в PHP эквивалент E_ALL ^ E_NOTICE error_reporting(E_ALL ^ E_NOTICE); // установка по умолчанию error_reporting(0); // отключить сообщения об ошибках
// общие ошибки выполнения error_reporting(E_ERROR | E_WARNING | E_PARSE); // также сообщать о неизвестных переменных
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); error_reporting(E_ALL); // сообщать все ошибки
restore_error_handler
Восстановление предыдущего обработчика ошибок.
Синтаксис :
void restore_error_handler()
Эта функция устанавливает в качестве функции обработчика ошибок ту, которая была таковой до последнего вызова функции set_error_handler(). Предыдущим обработчиком может быть ранее установленный пользовательский обработчик или встроенный обработчик PHP.
trigger_error
Генерация ошибки.
Синтаксис :
void trigger_error(string error_msg [, int error_type])
Явно вызывает функцию, установленную для обработки ошибок, и обычно используется в паре с обработчиком ошибок. Функция способна генерировать только пользовательские типы ошибок ( семейство констант E_USER), и по умолчанию, если не указан тип ошибки error_type, он считается E_USER_NOTICE.
Возможно конструировать сложные конструкции генерации и обработки ошибок и исключительных ситуаций.
if(assert($divisor == 0))
trigger_error («Нельзя делить на 0 «, E_USER_ERROR);
user_error
Синоним функции trigger_error().
Синтаксис :
void user_error(string error_msg [, int error_type])
Отслеживание и обработка ошибок : Установка пользовательского обработчика ошибок
set_error_handler
Установка пользовательского обработчика ошибок.
Синтаксис :
string set_error_handler(string error_handler)
Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в качестве нового обработчика, функцию с указанным в аргументе error_handler именем.
Обычно пользовательский обработчик ошибок работает в паре с функцией trigger_error(), генерирующей ошибку. Это может быть использовано (подобно аналогичной конструкции работы с исключениями в C) для освобождения выделенных ресурсов (например, удаления созданных файлов), если сценарий не может нормально завершиться.
Функция, устанавливаемая в качестве обработчика ошибок, должна принимать пять параметров (три последних являются дополнительными и могут не обрабатываться):
•код ошибки
•строку, описывающую ошибку
•имя сценария, в котором произошла ошибка
•номер строки сценария, содержащей ошибку
•контекст (массив, содержащий значения переменных, в момент возникновения ошибки)
<?
//определить константы пользовательских ошибок define(FATAL, E_USER_ERROR);
define(ERROR, E_USER_WARNING); define(WARNING, E_USER_NOTICE);
//установить, какие ошибки должны обрабатываться в сценарии error_reporting (FATAL | ERROR | WARNING);
//пользовательский обработчик ошибок
function myErrorHandler($errno,$errstr,$errfile,$errline) { switch ($errno) {
case FATAL:
echo «<b>Критическая ошибка</b> [$errno] $errstr<br>\n»; echo «в строке: $errline файла:».$errfile;
echo «, PHP «.PHP_VERSION.» («.PHP_OS.»)<br>\n»; echo «Aborting…<br>\n»;
exit -1; break; case ERROR:
echo «<b>Ошибка</b> [$errno] $errstr<br>\n»; break;
case WARNING:
echo «<b>Предупреждение</b> [$errno] $errstr<br>\n»; break;
default:
echo «Неизвестный тип ошибки: [$errno] $errstr<br>\n»;
}
}
//функция для проверки обработки ошибок
//(масштабирование массива
function scale_by_log($vect, $scale) { if(!is_numeric($scale) || $scale <= 0)
trigger_error(«вычислить log(x) для x <= 0 нельзя. «, «(x = $scale)», FATAL);
if(!is_array($vect)) { trigger_error(«Требуется массив «, ERROR); return null;
}
for($i=0; $i<count($vect); $i++) { if(!is_numeric($vect[$i]))
trigger_error(«Элемент ($i) не число и
его значением считается 0″, WARNING); $temp[$i]=log($scale)*$vect[$i];
}
return $temp;
}
// установить пользовательский обработчик ошибок $old_error_handler=set_error_handler(«myErrorHandler»);
$a=array(2,3,»foo»,5.5,43.3,21.11); print_r($a);
$b=scale_by_log($a,M_PI); // здесь выдается предупреждение echo «Массив, масштабированный на логарифм(Пи): «;
print_r($b);
$c=scale_by_log(«not array»,2,3); // здесь ошибка var_dump($c);
$d=scale_by_log($a, -2.5); // здесь критическая ошибка
echo «Продолжение сценария…»; ?>
При выполнении сценария вывод будет следующим:
Array
(
[0]=> 2
[1]=> 3
[2]=> foo
[3]=> 5.5
[4]=> 43.3
[5]=> 21.11
)
<b>Предупреждение</b> [1024] Элемент (2) не число, и его значением считается 0<br>
Массив, масштабированный на логарифм(Пи): Array
(
[0]=> 2.2894597716988
[1]=> 3.4341896575482
[2]=> 0
[3]=> 6.2960143721717
[4]=> 49.566804057279
[5]=> 24.165247890281
)
<b>Ошибка</b> [512] Требуется массив <br> NULL
<b>Критическая ошибка</b> [256] вычислить log(x) для x <=0 нельзя, (x = -2.5)<br>
в строке: 37, файла E:\www\exampl.php, PHP 4.0.5 (WINNT)<br> Aborting…<br>
Не забывайте, что при установке пользовательского обработчика ошибок стандартный обработчик PHP не используется. Установки error_reporting() также не будут иметь эффекта, и пользовательский обработчик должен уметь обрабатывать все виды ошибок (значение error_reporting() можно выяснить и действовать соответсвенно). Заметьте, что код ошибки будет равен 0, если ошибка возникла в функции, вывод ошибок для которой был блокирован оператором «@».
Также помните, что завершать сценарий в обработчике необходимо явно (например, с помощью функции die()), если, конечно, в этом есть необходимость. Если обработчик ошибок завершается с помощью return, то выполнение сценария продолжается с того места, в котором возникла ошибка (то есть исполняются инструкции, которые следуют за той инструкцией, в которой возникла ошибка).
Управление сессиями : Зачем нужны сессии.Механизм работы сессий
Зачем нужны сессии
Сессия представляет собой механизм, позволяющий хранить некоторые данные, индивидуальные для каждого пользователя (например, его имя и номер счета), между запусками сценария.
В Web-программировании есть один класс задач, который может вызвать довольно много проблем, если писать сценарий «в лоб». Речь идет о слабой стороне CGI — невозможности запустить программу на длительное время, позволив ей при этом обмениваться данными с пользователями.
Представте, что мы пишем форму, но в ней такое большое число полей, что было бы глупо поместить их на одну страницу. Нам нужно разбить процесс заполнения формы на несколько этапов, или стадий, и представить их в виде отдельных HTML-документов.
Например, в первом документе с диалогом у пользователя может запрашиваться его имя и фамилия, во втором — данные о его месте жительства, и в третьем — номер кредитной карточки. В любой момент можно вернуться на шаг назад, чтобы исправить те или иные данные. Наконец, если все в порядке, накопленная информация обрабатывается — например, помещается в базу данных.
Реализация такой схемы оказывается для Web-приложений довольно нетривиальной проблемой. Действительно, нам придется хранить все ранее введенные данные в каком-нибудь хранилище, которое должно аннулироваться, если пользователь вдруг передумает и уйдет с сайта. Для этого можно использовать функции сериализации и файлы. Однако ими мы решаем только половину проблемы: нам нужно как то привязать конкретного пользователя к конкретному временному хранилищу. Действительно, предположим, мы этого не сделали. Тогда, если в момент заполнения какой-нибудь формы одним пользователем на сайт зайдет другой и тоже попытается ввести свои данные, получится белеберда.
Все эти проблемы решаются при помощи сессий.
Механизм работы сессий
Для начала должен существовать механизм, который бы позволил PHP идентифицировать каждого пользователя, запустившего сценарий. То есть при следующем запуске PHP нужно однозначно определить, кто его запустил: тот же человек, или другой. Делается это путем присвоения клиенту так называемого уникального идентификатора сессии. Чтобы этот идентификатор был доступен при каждом запуске сценария, PHP помещает его Cookies браузера. Теперь, зная идентификатор (дальше SID), PHP может определить, в каком же файле на диске храняться данные пользователя.
Немного о том, как сохранять переменную (обязательно глобальную) в сессии. Для этого мы должны ее зарегестрировать с помощью специальной функции. После регистрации мы можем быть уверены, что при следующем запуске сценария тем же пользователем она получит то же самое значение, которое было у нее при предыдущем завершении программы. Это произойдет потому, что при завершении сценария PHP автоматически сохраняет все переменные, зарегестрированные в сессии, во временное хранилище. Конечно, можно в любой момент аннулировать переменную — вычеркнуть ее из сессии, или же уничтожить вообще все данные сессии.
Где же находиться то промежуточное хранилище, которое использует PHP? Вообще говоря, вы вольны сами это задать, написав соответствующие функции и зарегестрировав их как обработчики сессии. Впрочем, делать это не обязательно: в PHP уже существуют обработчики по умолчанию, которые хранят данные в файлах. Если вы не собираетесь создавать что-то особенное, вам они вполне подойдут.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #