PHP 错误处理
在本教程中,您将学习如何使用 PHP 的错误处理函数来优雅地处理错误情况。
处理错误
有时您的应用程序不会按预期运行,从而导致错误。可能导致错误的原因有很多,例如:
- Web 服务器可能磁盘空间不足
- 用户可能在表单字段中输入了无效值
- 您尝试访问的文件或数据库记录可能不存在
- 应用程序可能无权写入磁盘上的文件
- 应用程序需要访问的服务可能暂时不可用
这些类型的错误称为运行时错误,因为它们发生在脚本运行时。它们与脚本运行前需要修复的语法错误不同。
专业的应用程序必须具备优雅处理此类运行时错误的能力。通常这意味着更清楚、更准确地告知用户问题。
了解错误级别
通常,当出现阻止脚本正常运行的问题时,PHP 引擎会触发错误。每个错误都由一个整数值和一个相关的常数表示。下表列出了一些常见的错误级别:
错误级别 | 值 | 说明 |
---|---|---|
E_ERROR |
1 |
致命的运行时错误,无法从中恢复。 脚本的执行立即停止。 |
E_WARNING |
2 |
运行时警告。 它不是致命的,大多数错误都属于这一类。 脚本的执行不会停止。 |
E_NOTICE |
8 |
运行时通知。 表示脚本遇到了可能出错的情况,虽然正常运行脚本时也可能出现这种情况。 |
E_USER_ERROR |
256 |
用户生成的致命错误消息。 这类似于 E_ERROR ,除了它是由 PHP 脚本使用函数 trigger_error() 而不是 PHP 引擎生成的。 |
E_USER_WARNING |
512 |
非致命的用户生成的警告消息。 这类似于 E_WARNING ,只是它是由 PHP 脚本使用函数 trigger_error() 而不是 PHP 生成的。 引擎 |
E_USER_NOTICE |
1024 |
用户生成的通知消息。 这就像一个 E_NOTICE ,除了它是由 PHP 脚本使用函数 trigger_error() 而不是 PHP 引擎生成的。 |
E_STRICT |
2048 |
严格来说不是错误,而是在 PHP 遇到可能导致问题或向前不兼容的代码时触发 |
E_ALL |
8191 |
所有错误和警告,除了 PHP 5.4.0 之前的 E_STRICT 。 |
有关更多错误级别,请查看 PHP 错误级别上的参考。
PHP 引擎在遇到脚本问题时会触发错误,但您也可以自己触发错误以生成对用户更友好的错误消息。 通过这种方式,您可以使您的应用程序更加复杂。 以下部分描述了一些用于处理 PHP 中的错误的常用方法:
使用 die()
函数的基本错误处理
考虑以下示例,该示例仅尝试打开一个文本文件以进行只读。
示例
Download<?php
// 尝试打开一个不存在的文件
$file = fopen("sample.txt", "r");
?>
如果该文件不存在,您可能会收到如下错误:
如果我们遵循一些简单的步骤,我们可以防止用户收到此类错误消息。
示例
Download<?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 引擎生成的运行时错误。 自定义错误处理程序为您提供更大的灵活性并更好地控制错误,它可以检查错误并决定如何处理错误,它可能会向用户显示消息,将错误记录在文件或数据库中或通过 e 发送 -mail,尝试解决问题并继续,退出脚本的执行或完全忽略错误。
自定义错误处理函数必须能够处理至少两个参数(errno 和 errstr),但是它可以选择接受额外的三个参数(errfile、errline 和 errcontext),如下所述:
参数 | 说明 |
---|---|
Required — 以下参数是必需的 | |
errno | 以整数形式指定错误级别。 这对应于适当的错误级别常量(E_ERROR 、E_WARNING 等) |
errstr | 将错误消息指定为字符串 |
Optional — The following parameters are optional | |
errfile | 指定发生错误的脚本文件的文件名,作为字符串 |
errline | 以字符串形式指定发生错误的行号 |
errcontext | 指定一个数组,其中包含发生错误时存在的所有变量及其值。 对调试很有用 |
这是一个简单的自定义错误处理函数的示例。 这个处理程序,customError()
会在发生错误时触发,无论多么微不足道。 然后它将错误的详细信息输出到浏览器并停止脚本的执行。
示例
Download<?php
// 错误处理函数
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
?>
您需要告诉 PHP 使用您的自定义错误处理函数 — 只需调用内置的 set_error_handler()
函数,传入函数的名称。
示例
Download<?php
// 错误处理函数
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
// 设置错误处理程序
set_error_handler("customError");
// 触发错误
echo($test);
?>
错误记录
在文本文件中记录错误消息
您还可以将错误的详细信息记录到日志文件中,如下所示:
示例
Download<?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) . "\r\n";
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()
函数发送包含错误详细信息的电子邮件。
示例
Download<?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) . "\r\n";
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()
函数,并传入您要生成的错误消息:
考虑以下计算两个数字相除的函数。
示例
Download<?php
function calcDivision($dividend, $divisor){
return($dividend / $divisor);
}
// 调用函数
echo calcDivision(10, 0);
?>
如果将零 (0) 值作为 $divisor
参数传递,PHP 引擎生成的错误将如下所示:
这条消息看起来信息量不大。 考虑以下使用 trigger_error()
函数生成错误的示例。
示例
Download<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
// 调用函数
echo calcDivision(10, 0);
?>
现在脚本生成此错误消息:
如您所见,与前一个示例相比,第二个示例生成的错误消息更清楚地解释了问题。