PHP 错误处理是指在 PHP 代码中进行配置,以有效地识别程序可能遇到的运行时错误并从中恢复。在 PHP 中,错误是借助 -
- die() 函数
- 错误处理程序函数
die() 函数
die() 函数是 PHP 中 exit() 的别名。遇到这两种情况时,都会导致当前 PHP 脚本终止。如果在括号中指定了可选字符串,则将在程序终止之前输出。
die("message");
例子
以下代码是 die() 在 PHP 脚本中的典型用法。如果 PHP 找不到文件,则显示 “找不到文件” 消息,否则继续打开它进行后续处理。
<?php
if(!file_exists("nosuchfile.txt")) {
die("找不到文件");
} else {
$file = fopen("nosuchfile","r");
print "已成功打开文件";
// 其余的代码在这里。
fclose($file);
}
?>
它将产生以下输出 -
使用上述技术,您可以在程序出错时停止程序并显示更有意义和用户友好的消息,而不是让 PHP 生成致命错误消息。
错误处理程序函数
使用 die() 进行错误处理被认为是一种笨拙且糟糕的程序设计,因为它会给网站用户带来难看的体验。PHP 提供了一种更优雅的替代方案,您可以使用它来定义自定义函数并指定它来处理错误。
set_error_handler() 函数具有以下参数 -
set_error_handler(?callable $callback, int $error_levels = E_ALL): ?callable
第一个参数是用户定义的函数,每当遇到错误时都会自动调用该函数。
自定义错误处理程序回调函数应具有以下参数 -
handler(
int $errno,
string $errstr,
string $errfile = ?,
int $errline = ?,
array $errcontext = ?
): bool
参数
参数 | 重要性 | 描述 |
---|---|---|
errno | 必填 | 指定用户定义错误的错误级别。 它必须是数值。 |
errstr | 必填 | 指定用户定义错误的错误消息。 |
errfile | 自选 | 指定发生错误的文件名。 |
errline | 自选 | 指定发生错误的行号。 |
errcontext | 自选 | 指定一个数组,其中包含发生错误时使用的变量及其值。 |
如果回调函数返回 false,则调用默认错误。
$errno 是对应于预定义错误级别的整数。
常量 | 描述 | 值 |
---|---|---|
E_ERROR (int) | 无法恢复的致命运行时错误。脚本的执行已停止。 | 1 |
E_WARNING (int) | 运行时警告(非致命错误)。脚本的执行不会停止。 | 2 |
E_PARSE (int) | 编译时分析错误。解析错误应仅由解析器生成。 | 4 |
E_NOTICE (int) | 运行时通知。这可能表示错误,但也可能在运行脚本的正常过程中发生。 | 8 |
E_CORE_ERROR (int) | PHP 初始启动期间发生的致命错误。这就像一个E_ERROR | 16 |
E_CORE_WARNING (int) | PHP 初始启动期间发生的警告(非致命错误)。这就像一个E_WARNING, | 32 |
E_COMPILE_ERROR (int) | 致命的编译时错误。这就像一个E_ERROR。 | 64 |
E_COMPILE_WARNING (int) | 编译时警告(非致命错误)。这就像一个E_WARNING。 | 128 |
E_USER_ERROR (int) | 用户生成的错误消息。这类似于使用 PHP 函数 trigger_error() 在 PHP 代码中生成的E_ERROR。 | 256 |
E_USER_WARNING (int) | 用户生成的警告消息。这类似于 E_WARNING,使用函数 trigger_error() 在 PHP 代码中生成。 | 512 |
E_USER_NOTICE (int) | 用户生成的通知消息。这类似于使用函数 trigger_error() 在 PHP 代码中生成的E_NOTICE。 | 1024 |
E_STRICT (int) | 启用此选项可让 PHP 建议对代码进行更改,这将确保代码的最佳互操作性和向前兼容性。 | 2048 |
E_RECOVERABLE_ERROR (int) | 可捕获的致命错误。如果用户定义的处理程序未捕获错误,则应用程序将中止,因为它是一个E_ERROR。 | 4096 |
E_DEPRECATED (int) | 运行时通知。启用此选项可接收有关代码在将来版本中不起作用的警告。 | 8192 |
E_USER_DEPRECATED (int) | 用户生成的警告消息。这类似于 E_DEPRECATED,使用函数 trigger_error() 在 PHP 代码中生成。 | 16384 |
E_ALL (int) | 所有错误、警告和通知。 | 32767 |
例子
请看下面的例子 -
<?php
error_reporting(E_ERROR);
function myerrorhandler($errno, $errstr) {
echo "错误编号: $errno 错误信息: $errstr" . PHP_EOL;
echo "终止PHP脚本";
die();
}
set_error_handler("myerrorhandler");
$f = fopen("nosuchfile.txt", "r");
echo "文件已成功打开";
// 其余代码
fclose($f);
?>
它将产生以下输出 -
such file or directory
终止PHP脚本
PHP 的 error 类层次结构从 throwable 接口开始。PHP 所有预定义的 Error 类都是从 Error 类继承的。
ArithmeticError 类
ArithmeticError 类继承自 Error 类。在执行某些数学运算(例如按负量执行按位移位运算)时,可能会发生此类错误。
例子
请看下面的例子 -
<?php
try {
$a = 10;
$b = -3;
$result = $a << $b;
}
catch (ArithmeticError $e) {
echo $e->getMessage();
}
?>
将产生以下输出 -
当调用 intdiv() 函数导致 值 超出整数的合法边界时,也会引发此错误。
例子
请看下面的例子 -
<?php
try {
$a = PHP_INT_MIN;
$b = -1;
$result = intdiv($a, $b);
echo $result;
}
catch (ArithmeticError $e) {
echo $e->getMessage();
}
?>
将产生以下输出 -
DivisionByZeroError (除法零错误)
DivisionByZeroError 类是 ArithmeticError 类的子类。当除法运算中分母的值为零时,会出现这种类型的错误。
示例:以零取模
请看以下示例:
<?php
try {
$a = 10;
$b = 0;
$result = $a%$b;
echo $result;
}
catch (DivisionByZeroError $e) {
echo $e->getMessage();
}
?>
它将产生以下输出 -
当模运算符 (%) 的第二个运算符为 0,而 intdiv() 函数的第二个参数为 0 时,也会发生这种情况。
示例:除以零
请看下面的例子 -
<?php
try {
$a = 10;
$b = 0;
$result = $a/$b;
echo $result;
}
catch (DivisionByZeroError $e) {
echo $e->getMessage();
}
?>
它将产生以下输出 -
ArgumentCountError
当传递给用户定义的函数或方法的参数小于其定义中的参数时,PHP 解析器会抛出 ArgumentCountError。
例子
请看下面的例子 -
<?php
function add($x, $y) {
return $x+$y;
}
try {
echo add(10);
}
catch (ArgumentCountError $e) {
echo $e->getMessage();
}
?>
它将产生以下输出 -
TypeError (类型错误)
当 实际参数类型 和 形式参数类型 不匹配时,会引发此错误,返回类型与声明的返回类型不匹配。
例子
请看下面的例子 -
<?php
function add(int $first, int $second) {
echo "addition: " . $first + second;
}
try {
add('first', 'second');
}
catch (TypeError $e) {
echo $e->getMessage(), "";
}
?>
它将产生以下输出 -
called in /home/cg/root/63814/main.php on line 7
当 PHP 内置函数传递的参数数量不正确时,也会引发 TypeError。但是,必须在开始时设置 “strict_types=1” 指令。
例子
请看下面的例子 -
<?php
declare(strict_types=1);
try {
echo pow(100,2,3);
}
catch (TypeError $e) {
echo $e->getMessage(), "";
}
?>
它将产生以下输出 -
PHP 异常处理
PHP 具有与其他编程语言类似的异常模型。异常很重要,可以更好地控制错误处理。
让我们解释一下与异常相关的新关键字。
关键词 | 描述 |
---|---|
Try | 使用异常的函数应位于 “try” 块中。如果异常未触发,代码将照常继续。但是,如果触发了异常,则会“引发”异常。 |
Throw | 这是触发异常的方式。每个 “throw” 必须至少有一个 “catch”。 |
Catch | “catch” 块检索异常并创建包含异常信息的对象。 |
当抛出异常时,该语句后面的代码将不会被执行,PHP 将尝试找到第一个匹配的 catch 块。如果未捕获到异常,将发出 PHP 致命错误,并显示“未捕获的异常...
- 在 PHP 中可以引发异常并捕获 (“catched”) 异常。代码可能括在 try 块中。
- 每个 try 必须至少有一个相应的 catch 块。多个 catch 块可用于捕获不同类别的异常。
- 可以在 catch 块中引发 (或重新引发) 异常。
例子
以下是一段代码,将此代码复制并粘贴到文件中并验证结果。
<?php
try {
$error = '总是抛出此错误';
throw new Exception($error);
// 异常后的代码不会执行。
echo 'Never executed';
}catch (Exception $e) {
echo '捕获异常: ', $e->getMessage(), "";
}
// 继续执行
echo 'Hello World';
?>
在上面的例子中,$e->getMessage 函数用于获取错误消息。Exception 类中可以使用以下函数。
值 | 意义 |
---|---|
getMessage() | 异常消息 |
getCode() | 异常代码 |
getFile() | 源文件名 |
getLine() | 源行 |
getTrace() | backtrace() 的 n 数组 |
getTraceAsString() | 格式化的跟踪字符串 |
创建自定义异常处理程序
您可以定义自己的自定义异常处理程序。使用以下函数设置用户定义的异常处理程序函数。
string set_exception_handler ( callback $exception_handler )
此处 exception_handler 是发生未捕获的异常时要调用的函数的名称。此函数必须在调用 set_exception_handler() 之前定义。
例子
请看下面的例子 -
<?php
function exception_handler($exception) {
echo "未捕获的异常: " , $exception->getMessage(), "\n";
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
echo "未执行";
?>
在 PHP 错误处理函数 检查完整的错误处理函数集