php的异常处理机制可以让开发者主动捕获程序运行中出现的错误,避免错误直接导致程序崩溃,同时还能将错误信息规范化处理,方便后续的日志记录和问题排查。php主要通过trycatch结构来实现异常的捕获和处理,配合throw关键字抛出自定义异常,形成完整的异常处理流程。

php异常处理的基础概念
异常是指在程序执行过程中发生的、打断正常执行流程的特殊情况,比如调用不存在的函数、访问越界的数组、数据库连接失败等。php中所有的异常都是Exception类的实例,Exception类内置了几个常用的方法,方便获取异常相关信息:
- getMessage():获取异常的描述信息
- getCode():获取异常的代码
- getFile():获取异常发生的文件路径
- getLine():获取异常发生的行号
trycatch结构的基本语法
trycatch是php处理异常的核心结构,基本语法格式如下:
<?php
try {
// 可能会触发异常的代码逻辑
// 如果这里出现问题,可以手动抛出或者由系统抛出异常
} catch (Exception $e) {
// 捕获到异常后的处理代码
// $e 是捕获到的异常对象,可以调用其方法获取异常信息
} finally {
// 可选部分,无论是否捕获到异常,这里的代码都会执行
}
?>
需要注意的是,try块后面必须至少跟一个catch块或者finally块,不能单独使用try块。finally块是可选的,通常用于释放资源,比如关闭打开的文件、断开数据库连接等。
trycatch的基本使用示例
下面通过一个简单的示例演示trycatch的基本用法,首先演示手动抛出异常的情况:
<?php
function divide($a, $b) {
if ($b == 0) {
// 手动抛出除以0的异常
throw new Exception("除数不能为0");
}
return $a / $b;
}
try {
$result = divide(10, 0);
echo "计算结果:" . $result;
} catch (Exception $e) {
echo "捕获到异常:" . $e->getMessage() . "<br/>";
echo "异常发生文件:" . $e->getFile() . "<br/>";
echo "异常发生行号:" . $e->getLine();
}
?>
上面的代码中,调用divide函数时传入了除数为0的参数,函数内部主动抛出了异常,try块中的后续代码不会执行,直接进入catch块处理异常,最终会输出异常的相关信息。
捕获不同类型的异常
php支持在一个try块后面跟多个catch块,用来捕获不同类型的异常,需要注意的是,子类异常的catch块要放在父类异常的catch块前面,否则子类异常会被父类异常的catch块提前捕获。示例代码如下:
<?php
// 自定义一个数据库异常类,继承Exception
class DatabaseException extends Exception {}
// 自定义一个文件操作异常类,继承Exception
class FileException extends Exception {}
function readConfig() {
// 模拟文件不存在的情况,抛出文件异常
throw new FileException("配置文件不存在");
}
try {
readConfig();
} catch (FileException $e) {
echo "文件操作异常:" . $e->getMessage();
} catch (DatabaseException $e) {
echo "数据库异常:" . $e->getMessage();
} catch (Exception $e) {
echo "通用异常:" . $e->getMessage();
}
?>
自定义异常类的实现
除了使用系统自带的Exception类,开发者还可以根据业务需求自定义异常类,自定义异常类只需要继承Exception类即可,还可以添加自定义的方法和属性。示例代码如下:
<?php
class UserException extends Exception {
private $errorCode;
public function __construct($message, $errorCode) {
parent::__construct($message);
$this->errorCode = $errorCode;
}
public function getErrorCode() {
return $this->errorCode;
}
}
function checkUserAge($age) {
if ($age < 18) {
throw new UserException("用户年龄未满18岁,无法操作", 1001);
}
return true;
}
try {
checkUserAge(15);
} catch (UserException $e) {
echo "用户异常:" . $e->getMessage() . "<br/>";
echo "错误码:" . $e->getErrorCode();
}
?>
异常处理的注意事项
在使用php处理异常时,有几个需要注意的点:
- 不要滥用异常处理,普通的流程控制不要用异常来实现,比如用异常判断用户是否登录,这种方式会降低代码可读性
- 如果没有捕获异常,php会按照默认的方式处理,致命错误会直接终止程序,非致命错误会输出警告信息
- finally块中的代码在return语句之前执行,即使try块或者catch块中有return,finally块还是会先执行
- php7之后,很多错误(比如调用不存在的函数)会被转换为
Error类的异常,Error和Exception都实现了Throwable接口,所以可以用catch (Throwable $e)来捕获所有的错误和异常
如果需要同时捕获异常和错误,可以使用Throwable接口作为捕获类型,示例代码如下:
<?php
try {
// 调用不存在的函数,会产生Error
testFunction();
} catch (Throwable $e) {
echo "捕获到错误或者异常:" . $e->getMessage();
}
?>