PHP 异常处理完整指南
                           
天天向上
发布: 2025-03-21 00:08:34

原创
233 人浏览过

1. 什么是异常处理?

异常(Exception)是 PHP 处理程序错误的一种机制。当程序运行时遇到无法继续执行的情况(如数据库连接失败、文件未找到等),可以通过 异常 机制捕获错误并做相应处理,而不是直接导致程序崩溃。


2. try-catch 捕获异常

PHP 提供了 try-catch 机制来捕获和处理异常:

基本示例

function divide($a, $b) {
    if ($b == 0) {
        throw new Exception("除数不能为零");
    }
    return $a / $b;
}

try {
    echo divide(10, 0);
} catch (Exception $e) {
    echo "捕获到异常: " . $e->getMessage();
}

📌 解释

  • throw new Exception("除数不能为零"):抛出异常
  • try 块中放置可能出错的代码
  • catch (Exception $e) 捕获 Exception 并处理错误

3. try-catch 捕获多个异常

PHP 允许 catch 块处理多种异常类型:

class CustomException extends Exception {}
class AnotherException extends Exception {}

try {
    throw new CustomException("自定义异常");
} catch (CustomException $e) {
    echo "捕获 CustomException: " . $e->getMessage();
} catch (AnotherException $e) {
    echo "捕获 AnotherException: " . $e->getMessage();
} catch (Exception $e) {
    echo "通用异常: " . $e->getMessage();
}

📌 优先级

  • catch 按顺序匹配异常类型,先匹配的会被执行
  • Exception 作为通用异常处理,需放在最后

4. finally 语句

finally 代码块 无论是否发生异常都会执行,适用于资源清理(如关闭数据库连接)。

示例

function processFile($filename) {
    $file = fopen($filename, "r");
    try {
        if (!$file) {
            throw new Exception("无法打开文件");
        }
        echo "文件打开成功";
    } catch (Exception $e) {
        echo "错误: " . $e->getMessage();
    } finally {
        if ($file) {
            fclose($file);
            echo "文件已关闭";
        }
    }
}

processFile("test.txt");

📌 适用场景

  • 关闭数据库连接
  • 释放文件资源
  • 记录日志

5. 自定义异常

PHP 允许创建自定义异常类,继承 Exception

示例

class MyException extends Exception {
    public function customFunction() {
        return "异常代码: {$this->getCode()}, 消息: {$this->getMessage()}";
    }
}

try {
    throw new MyException("自定义错误", 1001);
} catch (MyException $e) {
    echo $e->customFunction();
}

📌 常用 Exception 方法

方法作用
getMessage()获取异常消息
getCode()获取异常代码
getFile()获取异常发生的文件
getLine()获取异常发生的行号
getTrace()获取异常跟踪数组
getTraceAsString()获取异常跟踪的字符串

6. set_exception_handler() 处理全局异常

如果异常未被 catch 处理,PHP 会终止脚本。可以用 set_exception_handler() 捕获所有未处理的异常。

示例

function globalExceptionHandler($exception) {
    error_log("未捕获异常: " . $exception->getMessage(), 3, "/var/log/php_exceptions.log");
    echo "系统错误,请稍后再试。";
}

// 设置全局异常处理
set_exception_handler("globalExceptionHandler");

// 触发异常
throw new Exception("数据库连接失败");

📌 适用场景

  • 记录异常日志
  • 统一返回友好的错误信息
  • 发送异常通知

7. PHP 7+ 错误处理(Error vs. Exception)

PHP 7 引入了 Error 类,使得错误(如调用未定义的函数)也可以像 Exception 一样被捕获。

示例

try {
    nonExistentFunction(); // PHP 7+ 允许捕获这种错误
} catch (Error $e) {
    echo "捕获到错误: " . $e->getMessage();
}

📌 适用场景

  • 兼容 PHP 7+ 的错误处理
  • 捕获 E_ERROR 级别的致命错误

8. 结合日志系统(Monolog)

在生产环境中,推荐使用 Monolog 进行日志管理:

composer require monolog/monolog
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('app');
$log->pushHandler(new StreamHandler('/var/log/app.log', Logger::ERROR));

try {
    throw new Exception("API 访问失败");
} catch (Exception $e) {
    $log->error($e->getMessage());
}

📌 Monolog 可将异常记录到文件、Slack、数据库等


9. 结合 HTTP 状态码

对于 Web API 或 RESTful 接口,可以结合 HTTP 状态码返回异常信息:

try {
    throw new Exception("未授权访问", 401);
} catch (Exception $e) {
    http_response_code($e->getCode());
    echo json_encode(["error" => $e->getMessage()]);
}

📌 适用场景

  • 401:未授权
  • 403:禁止访问
  • 404:资源未找到
  • 500:服务器内部错误

10. 异常处理最佳实践

开发环境

  • display_errors = On
  • error_reporting = E_ALL
  • 使用 try-catch 捕获异常

生产环境

  • display_errors = Off
  • log_errors = On
  • set_exception_handler() 处理全局异常
  • 记录异常日志(如 Monolog

推荐

  • 自定义异常类,提供更有意义的错误信息
  • finally 处理资源清理
  • 捕获 Error 以兼容 PHP 7+
  • 结合 HTTP 状态码返回友好错误
  • 使用日志系统(如 Monolog

总结

方案说明
try-catch捕获并处理异常
catch 多异常处理不同类型异常
finally资源清理(如关闭数据库)
set_exception_handler()捕获全局异常
自定义异常类便于分类和管理
Monolog高级日志管理
Error 处理兼容 PHP 7+

这样可以 增强 PHP 应用的稳定性和可维护性,让你的代码更安全、易于调试!

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *