PHP Try Catch 示例:异常和错误处理教程
什么是异常?
错误是程序无法自行处理的意外程序结果。
错误通过修复程序来解决。错误的例子是无限循环,它会一直执行下去。
异常是程序可以自行处理的意外程序结果。
异常的例子包括尝试打开一个不存在的文件。
该异常可以通过创建文件或向用户提供搜索文件的选项来处理。
为什么要处理异常?
- 避免页面出现意外结果,这可能会让最终用户感到非常恼火或不快。
- 通过不公开恶意用户可能用来攻击我们应用程序的信息来提高我们应用程序的安全性。
- PHP 异常用于在发生任何可预测的错误时改变程序的正常流程。
PHP 错误处理
当错误发生时,根据您的配置设置,PHP 会在网页浏览器中显示错误消息,并提供有关所发生错误的信息。
PHP 提供了多种处理错误的方法。
我们将介绍三种(3)常用的方法;
- Die 语句 – die 函数将 echo 和 exit 函数结合在一起。当我们想在发生错误时输出一条消息并停止脚本执行时,它非常有用。
- 自定义错误处理程序 – 这些是用户定义的函数,当发生错误时会调用它们。
- PHP 错误报告 – 错误消息取决于您的 PHP 错误报告设置。当您不知道错误原因时,此方法在开发环境中非常有用。显示的信息可以帮助您调试应用程序。
错误处理示例
现在让我们看一些带有错误处理例程的简单示例。
假设我们开发了一个使用文本文件存储数据的应用程序。在尝试从文件中读取数据之前,我们可能需要检查文件是否存在。
以下代码实现了上述示例。
<?php $denominator = 0; echo 2 / $denominator; ?>
假设您将文件 simple_error.php 保存在 phptuts 文件夹中,请打开 URL https:///phptuts/simple_error.php
您将看到以下结果
从以上结果可以看出,这使得我们的应用程序看起来不专业,并且会让用户感到烦恼。
我们将修改上面的代码,为该应用程序编写一个错误处理程序。
<?php $denominator = 0; if ($denominator != 0) { echo 2 / $denominator; } else { echo "cannot divide by zero (0)"; } ?>
假设您将上述代码保存为 error_handling.php,请打开 URL https:///phptuts/error_handling.php
注意: 显示像上面那样的消息,而不是显示“文件未找到”这样的消息,是一种良好的安全实践。
让我们看另一个使用自定义错误处理程序的示例。
自定义错误处理程序将设置为默认的 PHP 错误处理函数,它将主要显示错误编号和消息。
以下代码说明了上述示例的实现。
<?php function my_error_handler($error_no, $error_msg) { echo "Opps, something went wrong:"; echo "Error number: [$error_no]"; echo "Error Description: [$error_msg]"; } set_error_handler("my_error_handler"); echo (5 / 0); ?>
打开 URL https:///phptuts/custom_error_handler.php 您将看到以下结果。
从上面的例子可以看出,自定义错误处理程序非常强大,因为
- 它们允许我们自定义错误消息。
- 自定义错误处理程序还可以包括将错误记录到文件/数据库、向开发人员发送电子邮件等。
现在让我们看一下第三种错误处理类型。我们将使用 PHP 内置函数 error_reporting。它具有以下基本语法。
<?php error_reporting($reporting_level); ?>
此处,
- “error_reporting”是 PHP 错误报告函数。
- “$reporting_level”是可选的,可用于设置报告级别。如果未指定报告级别,PHP 将使用 php.ini 文件中指定的默认错误报告级别。
报告级别 | 描述 | 示例 |
---|---|---|
E_WARNING | 仅显示警告消息。不中断脚本执行。 | error_reporting(E_WARNING); |
E_NOTICE | 显示在程序正常执行过程中可能发生的通知,或者可能是一个错误。 | error_reporting(E_NOTICE); |
E_USER_ERROR | 显示用户生成的错误,即自定义错误处理程序。 | error_reporting(E_USER_ERROR); |
E_USER_WARNING | 显示用户生成的警告消息。 | error_reporting(E_USER_WARNING); |
E_USER_NOTICE | 显示用户生成的通知。 | error_reporting(E_USER_NOTICE); |
E_RECOVERABLE_ERROR | 显示非致命错误,并且可以通过自定义错误处理程序进行处理。 | error_reporting(E_RECOVERABLE_ERROR); |
E_ALL | 显示所有错误和警告。 | error_reporting(E_ALL); |
错误和异常的区别
- 异常在被抛出后被捕获,而错误通常是不可恢复的。
- 异常以面向对象的方式处理。这意味着当抛出异常时,会创建一个包含异常详细信息的异常对象。
下表显示了异常对象的方法。
方法 | 描述 | 示例 |
---|---|---|
getMessage() | 显示异常的消息。 |
<?php echo $e->getMessage(); ?> |
getCode() | 显示代表异常的数字代码。 |
<?php echo $e->getCode(); ?> |
getFile() | 显示异常发生的文件的名称和路径。 |
<?php echo $e->getFile(); ?> |
getLine() | 显示异常发生的行号。 |
<?php echo $e->getLine(); ?> |
getTrace() | 显示异常发生前的回溯数组。 |
<?php print_r( $e->getTrace()); ?> |
getPrevious() | 显示当前异常之前的上一个异常。 |
<?php echo $e->getPrevious(); ?> |
getTraceAsString() | 将异常的回溯显示为字符串而不是数组。 |
<?php echo $e->getTraceAsString(); ?> |
__toString() | 将整个异常显示为字符串。 |
<?php echo $e->__toString(); ?> |
以下是抛出异常的基本语法。
<?php throw new Exception("This is an exception example"); ?>
此处,
- “throw”是用于抛出异常的关键字。
- “new Exception(…)”创建一个异常对象,并将“This is an exception example “字符串作为消息参数传递。
上面的代码输出以下消息。
现在我们将看一个实现 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 基本异常示例。
程序故意抛出一个异常,然后捕获它。
<?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 https:///phptuts/exception_handling.php 您将看到以下结果。
对于一个 PHP try 语句,根据抛出的异常类型,也可以创建多个异常。
请参阅关于MySQL、PHP 数据访问…的文章,了解多个异常的实现示例。
多个异常
多个异常使用多个 try 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 https:///phptuts/multiple_exceptions.php
切换回 PHP 文件,并将 -1 作为参数传递,如下所示。
浏览到 URL https:///phptuts/multiple_exceptions.php。
您会得到什么结果?将 3 作为参数传递。
您会得到什么结果?
摘要
- 错误是 PHP 代码产生的意外结果。
- 错误处理可提高应用程序性能。
- PHP 具有可用于自定义 PHP 报告错误方式的内置函数。
- 异常类似于错误,但它们可以在抛出时使用 catch 块进行捕获。
- 显示显示错误信息的错误消息被认为是不安全的。