为什么PDOException不能被set_error_handler、set_exception_handler所捕获

发布于 2022-09-12 13:09:09 字数 3798 浏览 13 评论 0

入口文件注册错误处理机制

// 设定报错级别为全部
error_reporting(E_ALL);
// 设定错误日志记录文件
ini_set('error_log',SYSTEM_LOGS_DIR.date("Ymd") . '_log.txt');
// 显示错误日志
ini_set('display_errors', '1');
// set_error_handler — 设置用户自定义的错误处理函数
set_error_handler([__CLASS__, 'appError']);
// set_exception_handler — 设置用户自定义的异常处理函数
set_exception_handler([__CLASS__, 'appException']);
// register_shutdown_function — 注册一个会在php中止时执行的函数,脚本执行完成或者 exit() 后被调用
register_shutdown_function([__CLASS__, 'appShutdown']);

但是当pdo insert的时候,如果我的字段过长
出现data too long for column的时候这两个函数都没有捕获到
只能通过到

try{
    $WorkListModelObj->insert($historyWork);
}catch(\Throwable $e){
    // PDOException
    echo $e->getCode();
    echo $e->getMessage();
}

所捕获到,这是为啥,有时候数组 undefined index 的时候:

PHP Notice:  Undefined index: test -- 无法被try-catch捕获-会被set_error_handler所捕获

有时候

// a();// PHP Fatal error:  Uncaught Error: Call to undefined function a()  -- try-catch也不能捕获
// php由上到下解析的,如果前面已经注册了set_exception_handler,那么将会被捕获,注意必须是这一行前面,不能是后面

我凌乱了
如何才能实现一个完美捕获所有php错误和异常并进行自己处理的程序

附上:

<?php

/**
 * 
 * 错误处理机制
 * @author wystanxu <435861851@qq.com>
 * @since 1.0.0
 * 
 */
class ErrorCatch
{
    /**
     * 注册异常处理
     * @access public
     * @return void
     */
    public static function register()
    {
        // 设定报错级别为全部
        error_reporting(E_ALL);
        // 设定错误日志记录文件
        ini_set('error_log', dirname(__DIR__) . '/' . date("Ymd") . '_log.txt');
        // 显示错误日志
        ini_set('display_errors', '1');
        // set_error_handler — 设置用户自定义的错误处理函数
        set_error_handler([__CLASS__, 'appError']);
        // set_exception_handler — 设置用户自定义的异常处理函数
        set_exception_handler([__CLASS__, 'appException']);
        // register_shutdown_function — 注册一个会在php中止时执行的函数,脚本执行完成或者 exit() 后被调用
        register_shutdown_function([__CLASS__, 'appShutdown']);
    }

    /**
     * 错误处理
     * @access public
     * @param  integer $errno      错误编号
     * @param  integer $errstr     详细错误信息
     * @param  string  $errfile    出错的文件
     * @param  integer $errline    出错行号
     * @param  array   $errcontext 出错上下文
     * @return void
     * @throws ErrorException
     */
    public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
    {
        echo "appErr";
        $msg = '错误编号:' . $errno . "\n\r";
        $msg .= '错误信息:' . $errstr . "\n\r";
        $msg .= '文件:' . $errfile . "\n\r";
        $msg .= '在第:' . $errline . "行\n\r";
        echo $msg;
        // 记录错误日志到文本
        error_log($msg, 3, ini_get("error_log"));
    }

    /**
     * 异常处理
     * @access public
     * @param   Exception $e 异常对象
     * @return void
     */
    public static function appException($exception)
    {
        $msg = "捕获异常: ".$exception->getMessage()."\n\r";
        echo $msg;
        // 记录错误日志到文本
        error_log($msg, 3, ini_get("error_log"));
    }

    /**
     * 异常中止处理
     * @access public
     * @return void
     */
    public static function appShutdown()
    {
        // 只有错误导致的程序终止才会托管至错误处理函数
        if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
            echo "appShutdown".PHP_EOL;
            self::appException(new ErrorException(
                $error['type'],
                $error['message'],
                $error['file'],
                $error['line']
            ));
        }
    }

    /**
     * 确定错误类型是否致命
     * @access protected
     * @param  int $type 错误类型
     * @return bool
     */
    protected static function isFatal($type)
    {
        return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);
    }
}

// 注册自定义错误处理
ErrorCatch::register();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无尽的现实 2022-09-19 13:09:09

错误和异常级别不一样,有的错误和异常会直接终止脚本。

在 index.php 中引入另一个文件 controller.php , 在 index.php 捕获 controller.php 异常和错误,执行 index.php 。

这样的话就算 controller.php 抛出严重的错误和异常,导致 controller.php 脚本终止,但并不影响 index.php ,在 index.php 中可以正常捕获到异常。

一绘本一梦想 2022-09-19 13:09:09

image.png
这样自己写脚本注册错误处理能正常捕获到,但是在phalcon框架之中是不能捕获到
Emm.. 运行后输出:
`
捕获异常: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (usin
g password: NO)
`

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文