PHP Try Catch 示例:异常和错误处理教程
⚡ 智能摘要
PHP 中的错误处理和异常机制通过管理意外情况而非直接暴露原始错误,来确保应用程序的稳定性和安全性。本教程将解释错误与异常的区别、die 语句、自定义错误处理程序、错误报告级别,以及包含多种异常类型的 try、throw 和 catch 异常模型。

什么是异常?
错误是程序本身无法处理的意外程序结果。
错误可以通过修复程序来解决。错误的一个例子是永不停止执行的无限循环。
异常是指程序自身可以处理的意外程序结果。
异常情况的例子包括尝试打开一个不存在的文件。
可以通过创建文件或向用户提供搜索文件的选项来处理此异常。
为什么要处理异常?
- 避免在我们的页面上出现意外结果,因为这可能会给我们的最终用户带来极大的困扰或恼怒。
- 通过不暴露恶意用户可能用来攻击我们应用程序的信息来提高我们应用程序的安全性
- PHP异常用于在发生任何可预见的错误时改变程序的正常流程。
PHP 错误处理
发生错误时,根据您的配置设置, PHP 在 Web 浏览器中显示错误消息,其中包含与发生的错误相关的信息。
PHP 提供了多种错误处理方式。我们将介绍三种常用的方法:
- 模具报表 die 函数将 echo 和 exit 函数合二为一。当发生错误时,我们想要输出一条消息并停止脚本执行,这个函数非常有用。
- 自定义错误处理程序 – 这些是用户定义的函数,在发生错误时被调用。
- PHP 错误报告 错误信息取决于您的 PHP 错误报告设置。当您在开发环境中完全不知道错误原因时,此方法非常有用。显示的信息可以帮助您调试应用程序。
错误处理示例
现在让我们来看一些带有错误处理程序的简单示例。
假设我们有一个计算可能会出现除以零的情况。我们希望优雅地处理这种情况,而不是让 PHP 显示原始错误信息。
下面的代码实现了上面的例子。
<?php
$denominator = 0;
echo 2 / $denominator;
?>
假设您已将 simple_error.php 文件保存在 phptuts 文件夹中,请打开该文件。 URL http://localhost/phptuts/simple_error.php
您将获得以下结果。
从上面的结果可以看出,它使我们的应用程序看起来不专业并且会让用户感到烦恼。
我们将修改上述代码,并为应用程序编写错误处理程序。
<?php $denominator = 0; if ($denominator != 0) { echo 2 / $denominator; } else { echo "cannot divide by zero (0)"; } ?>
假设您已将上述代码保存为 error_handling.php,请打开该文件。 URL http://localhost/phptuts/error_handling.php
注意: 显示如上所示的消息而不是显示“文件未找到”之类的原始消息是一种良好的安全做法。
让我们来看另一个使用自定义错误处理程序的例子。
自定义错误处理程序将被设置为默认的 PHP 错误处理函数,并且基本上会显示错误编号和消息。
下面的代码说明了上述示例的实现。
<?php function my_error_handler($error_no, $error_msg) { echo "Oops, something went wrong:"; echo "Error number: [$error_no]"; echo "Error Description: [$error_msg]"; } set_error_handler("my_error_handler"); echo (5 / 0); ?>
打开 URL http://localhost/phptuts/custom_error_handler.php您将得到以下结果。
从上面的例子中可以看出,自定义错误处理程序非常强大,原因如下:
- 它们允许我们自定义错误消息。
- 自定义错误处理程序还可以包括将错误日志记录到文件或数据库中、向开发人员发送电子邮件以及类似操作。
现在我们来看第三种错误处理方式。我们将使用 PHP 内置的 error_reporting 函数。它的基本语法如下。
<?php error_reporting($reporting_level); ?>
这里,
- “error_reporting” 是 PHP 错误报告函数
- “$reporting_level”是可选参数,可用于设置报告级别。如果未指定报告级别,PHP 将使用 php.ini 文件中指定的默认错误报告级别。
| 报告级别 | 描述 | 例如: |
|---|---|---|
| E_警告 | 仅显示警告消息。不会停止脚本的执行 | 错误报告(E_WARNING); |
| E_NOTICE | 显示程序正常执行期间可能发生的通知或可能是错误的通知。 | 错误报告(紧急通知); |
| 用户错误 | 显示用户生成的错误,即自定义错误处理程序 | 错误报告(E_USER_ERROR); |
| 用户警告 | 显示用户生成的警告消息 | 错误报告(E_USER_WARNING); |
| E_USER_NOTICE | 显示用户生成的通知 | 错误报告(E_USER_NOTICE); |
| 可恢复错误 | 显示非致命性错误,这些错误可以使用自定义错误处理程序进行处理。 | 错误报告(E_RECOVERABLE_ERROR); |
| 全部 | 显示所有错误和警告 | 错误报告(E_ALL); |
错误和异常之间的区别
- 异常会被抛出并需要被捕获,而错误通常是无法恢复的。
- 异常处理采用面向对象的方式。这意味着当抛出异常时,会创建一个包含异常详细信息的异常对象。
下表显示了异常对象的方法。
| 付款方式 | 描述 | 例如: |
|---|---|---|
| getMessage() | 显示异常的消息 |
<?php
echo $e->getMessage();
?>
|
| 得到Code() | 显示代表异常的数字代码 |
<?php
echo $e->getCode();
?>
|
| 获取文件() | 显示发生异常的文件名和路径 |
<?php
echo $e->getFile();
?>
|
| 获取线() | 显示发生异常的行号 |
<?php
echo $e->getLine();
?>
|
| 得到Trace () | 显示背面数组trac异常之前 |
<?php print_r( $e->getTrace()); ?> |
| 获取上一个() | 显示当前异常之前的前一个异常 |
<?php
echo $e->getPrevious();
?>
|
| 得到TraceAsString() | 显示背面trac将异常信息以字符串形式而不是数组形式表示。 |
<?php
echo $e->getTraceAsString();
?>
|
| __toString() | 将整个异常显示为字符串 |
<?php
echo $e->__toString();
?>
|
以下是引发异常的基本语法。
<?php throw new Exception("This is an exception example"); ?>
这里,
- “throw”是用于抛出异常的关键字
- “new Exception(…)” 创建一个异常对象,并将“这是一个异常示例”字符串作为消息参数传递。
上述代码输出以下消息。
现在我们将来看一个实现 throw 和 catch 异常的示例。我们将修改上面的示例,并添加 try、throw 和 catch 语句。
它具有以下基本语法。
<?php try { // code goes here that could potentially throw an exception } catch (Exception $e) { // exception handling code goes here } ?>
这里,
- “try{…}” 是可能引发异常的要执行的代码块
- “catch(Exception $e){…}”是捕获抛出的异常并将异常对象赋给变量$e的代码块。
以下代码展示了一个基本的异常处理示例,其中实现了 try、throw 和 catch 语句。程序会故意抛出一个异常,然后再将其捕获。
<?php try { $var_msg = "This is an exception example"; throw new Exception($var_msg); } catch (Exception $e) { echo "Message: " . $e->getMessage(); echo ""; echo "getCode(): " . $e->getCode(); echo ""; echo "__toString(): " . $e->__toString(); } ?>
打开 URL http://localhost/phptuts/exception_handling.php您将得到以下结果。
还可以根据抛出的异常类型,为一个 PHP try 语句创建多个异常。
请参阅文章 MySQLPHP 数据访问实现示例,用于处理多个异常。
多个例外
多个异常处理使用多个 catch 代码块来处理抛出的异常。多个异常处理在以下情况下很有用:
- 您希望根据抛出的异常显示自定义消息
- 您希望根据抛出的异常执行唯一的操作
下面的流程图说明了多个异常是如何工作的。
让我们来看一个使用多个异常的例子。我们将修改将一个数字除以传入分母的代码。
我们预计会出现两种类型的例外情况:
- 被零除
- 除以负数
为了简单起见,我们只会在 catch 代码块中显示异常类型。PHP 内置的 Exception 类用于抛出异常。我们将创建两个继承自 Exception 类的类,并使用它们来抛出异常。
下面的代码展示了实现过程。
<?php class DivideByZeroException extends Exception {}; class DivideByNegativeException extends Exception {}; function process($denominator) { try { if ($denominator == 0) { throw new DivideByZeroException(); } else if ($denominator < 0) { throw new DivideByNegativeException(); } else { echo 25 / $denominator; } } catch (DivideByZeroException $ex) { echo "DIVIDE BY ZERO EXCEPTION!"; } catch (DivideByNegativeException $ex) { echo "DIVIDE BY NEGATIVE NUMBER EXCEPTION!"; } catch (Exception $x) { echo "UNKNOWN EXCEPTION!"; } } process(0); ?>
测试代码
我们假设您已将 multiple_exceptions.php 保存在 phptuts 文件夹中。
浏览到 URL http://localhost/phptuts/multiple_exceptions.php
切换回 PHP 文件并传递 -1 作为参数,如下图所示。
浏览到 URL http://localhost/phptuts/multiple_exceptions.php你得到什么结果?现在将参数设为 3。你得到什么结果?
最后,阻塞和 PHP 7 错误模型
现代 PHP 在上述模型的基础上增加了两个重要组成部分。无论是否抛出异常,finally 代码块都会在 try 和 catch 代码块之后执行,这使其成为清理工作的理想选择,例如关闭文件或数据库连接。
自 PHP 7 起,许多以前致命的错误现在都以 Error 对象的形式抛出。Exception 和 Error 都实现了 Throwable 接口,因此 catch (\Throwable $e) 代码块可以处理其中任何一个。
<?php try { $result = 10 / 0; } catch (DivisionByZeroError $e) { echo "Caught: " . $e->getMessage(); } finally { echo "This message always runs"; } ?>
在 PHP 8 中,除以零会抛出 DivisionByZeroError 异常,catch 块会报告该异常,而 finally 块总是会运行,无论是否发生错误都会打印其消息。








