
Error
类的实例,使其可以像异常一样被捕获,这极大地增强了错误处理的灵活性。try
、catch
和throw
。try {
// 可能抛出异常的代码
$result = riskyOperation();
// 如果没有异常,继续执行
echo "操作成功: " . $result;
} catch (Exception $e) {
// 捕获并处理异常
echo "发生错误: " . $e->getMessage();
// 记录错误日志
error_log($e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine());
}
throw
关键字主动抛出异常:
function divide($numerator, $denominator) {
if ($denominator == 0) {
// 抛出新的异常实例
throw new Exception("除数不能为零");
}
return $numerator / $denominator;
}
Exception
类往往不够用,这时可以创建自定义异常类:
// 基础自定义异常
class AppException extends Exception {}
// 特定业务异常
class ValidationException extends AppException {
private $errors;
public function __construct($message, $errors = []) {
parent::__construct($message);
$this->errors = $errors;
}
public function getErrors() {
return $this->errors;
}
}
// 使用自定义异常
try {
$userInput = $_POST['email'];
if (!filter_var($userInput, FILTER_VALIDATE_EMAIL)) {
throw new ValidationException("邮箱格式无效", [
'email' => '请输入有效的邮箱地址'
]);
}
} catch (ValidationException $e) {
// 专门处理验证错误
$errors = $e->getErrors();
// 显示表单错误信息
} catch (AppException $e) {
// 处理其他应用异常
} catch (Exception $e) {
// 作为最后的异常捕获器
}
try {
// 可能抛出多种异常的代码
} catch (DatabaseConnectionException $e) {
// 处理数据库连接异常
} catch (QueryException $e) {
// 处理查询异常
} catch (AppException $e) {
// 处理其他应用异常
} catch (Exception $e) {
// 捕获所有未处理的异常
}
finally
块中的代码无论是否发生异常都会执行,适合释放资源:
$file = null;
try {
$file = fopen("data.txt", "r");
// 处理文件
} catch (Exception $e) {
echo "处理文件时出错: " . $e->getMessage();
} finally {
// 确保文件被关闭
if ($file) {
fclose($file);
}
}
set_exception_handler()
注册全局异常处理器,捕获未被处理的异常:
set_exception_handler(function($e) {
// 记录错误日志
error_log("未捕获的异常: " . $e->getMessage());
// 向用户显示友好信息
if (ENVIRONMENT === 'production') {
echo "抱歉,系统发生错误,请稍后再试";
} else {
// 开发环境显示详细错误
echo "异常: " . $e->getMessage() . "<br>";
echo "文件: " . $e->getFile() . "<br>";
echo "行号: " . $e->getLine() . "<br>";
echo "堆栈跟踪: " . $e->getTraceAsString();
}
});
try-catch
结构到自定义异常体系,再到全局异常处理策略,每一个环节都值得深入理解和实践。记住,优秀的异常处理不仅能帮助开发者快速定位问题,更能为用户提供流畅的使用体验,这正是专业开发的体现。