关于异常(Exception)的处理

<?php
declare(strict_types=1);
ini_set('display_errors', 'On'); // 关闭打印错误信息
ini_set('error_reporting', E_ALL & ~E_DEPRECATED & ~E_STRICT); // 报告部分级别错误
ini_set('display_startup_errors', 'Off'); // 不显示启动过程中的错误
ini_set('log_errors', 'Off'); // 不记录脚本运行错误
ini_set('error_log', null); // 指定脚本运行错误日志文件

/**
 * 异常(Exception)处理函数
 *
 * @param Exception $e Exception实例
 * @return void exit
 */
function exception_log(Exception $e): void
{
    $class = $e::class; // 获取异常类名,虽然形参是Exception类,但实际类型不一定和形参一致
    $message = $e->getMessage(); // 获取异常消息内容
    $file = $e->getFile(); // 获取发生异常的程序文件名称
    $line = $e->getLine(); // 获取发生异常的代码在文件中的行号
    $traceAsString = $e->getTraceAsString(); // 获取异常追踪信息(即堆栈踪迹)

    // 仿照标准错误处理程序的格式
    $data = "Fatal error: Uncaught $class: $message in $file:$line" . PHP_EOL;
    $data .= 'Stack trace:' . PHP_EOL;
    $data .= $traceAsString . PHP_EOL;
    $data .= "  thrown in $file on line $line";

    // 加上错误发生时间
    $data = '[' . date('Y-m-d H:i:s') . "] $data" . PHP_EOL;

    // 错误日志文件
    $filename = __DIR__ . '/error.log';

    // 将错误信息写入错误日志文件
    file_put_contents($filename, $data, FILE_APPEND | LOCK_EX);

    // 向开发者发送告警邮件或短信,通知尽快修复错误
    // send_sms();

    // 向用户展示友好错误提示然后中止程序
    exit('系统异常,请稍后再试~~~');
}

$dsn = 'mysql:host=localhost;port=3306;dbname=test_db;charset=utf8mb4;';
$username = 'ZhangSan';
$password = '********';

try {
    $pdo = new PDO($dsn, $username, md5($password));
} catch (Exception $e) {
    exception_log($e);
}


//========== 总结 ==========//
// 1、任何函数或方法,只要它可能抛出异常,就必须使用try-catch将异常捕获(不管是继续往上抛还是处理),否则程序会报致命错误(Fatal error)。
// 2、在实际开发中,推荐由顶层来对异常做最终处理(通常是向用户展示友好错误提示然后中止程序),中间层和底层只负责将异常往上抛不做具体处理,
//    直至将异常抛到最顶层,此时顶层无论如何都必须使用try-catch捕获异常,避免程序报致命错误(Fatal error)。

Copyright © 2024 码农人生. All Rights Reserved