PHP的异常处理机制是管控程序运行时错误的重要手段,通过规范的异常捕获与处理,可以避免错误直接导致程序崩溃,同时让错误信息的传递和处理更加可控。

PHP异常捕获的基础语法
PHP中最基础的异常捕获使用try、catch、finally三个关键字组合实现,基本结构如下:
<?php
try {
// 可能触发异常的代码逻辑
$num = 10;
if ($num > 5) {
throw new Exception("数值不能大于5");
}
} catch (Exception $e) {
// 捕获异常后的处理逻辑
echo "捕获到异常:" . $e->getMessage();
} finally {
// 无论是否触发异常都会执行的代码
echo "finally代码块执行完毕";
}
?>
其中throw关键字用于主动抛出一个异常对象,catch块用于匹配对应类型的异常并进行处理,finally块是可选部分,无论try块中是否触发异常,该块代码都会执行,通常用来做资源释放类的收尾工作。
捕获特定类型的异常
PHP支持捕获不同类型的异常,你可以在一个try块后跟随多个catch块,分别处理不同的异常类型:
<?php
class CustomException extends Exception {}
try {
$type = "error";
if ($type == "error") {
throw new CustomException("自定义异常触发");
}
} catch (CustomException $e) {
echo "处理自定义异常:" . $e->getMessage();
} catch (Exception $e) {
echo "处理通用异常:" . $e->getMessage();
}
?>
catch块的匹配顺序是从上到下,因此更具体的异常类型要放在更通用的异常类型之前,否则具体的异常会被通用异常捕获块提前处理。
自定义异常类的实现
除了使用PHP内置的Exception类,我们还可以根据业务需求自定义异常类,扩展异常的功能:
<?php
// 自定义异常类,继承Exception
class DatabaseException extends Exception {
private $sql;
public function __construct($message, $sql = "") {
parent::__construct($message);
$this->sql = $sql;
}
public function getSql() {
return $this->sql;
}
}
// 使用自定义异常
try {
$sql = "SELECT * FROM not_exist_table";
// 模拟数据库操作失败
throw new DatabaseException("数据库查询失败", $sql);
} catch (DatabaseException $e) {
echo "数据库异常:" . $e->getMessage() . "<br/>";
echo "出错的SQL语句:" . $e->getSql();
}
?>
自定义异常类可以添加业务相关的属性和方法,让异常信息更贴合实际场景,方便后续的错误排查和问题定位。
异常处理的常见最佳实践
- 不要滥用异常,只有非预期的错误情况才使用异常,普通的业务逻辑判断不建议用异常实现
- 异常捕获后要么处理完毕,要么重新抛出给上层调用者处理,不要捕获后不做任何处理直接忽略
- 生产环境不要直接输出异常的完整堆栈信息给用户,避免泄露敏感信息,可记录到日志中
- 如果不确定异常类型,可以捕获
Throwable接口,PHP7及以上版本中Error和Exception都实现了该接口
<?php
try {
// 可能触发Error或者Exception的代码
$a = 10 / 0;
} catch (Throwable $e) {
echo "捕获到Throwable类型错误:" . $e->getMessage();
}
?>