PHP PDO PDO::ATTR_SERVER_INFO 抛出异常时会触发一个警告

我是一名 Yaf 框架坚定的支持者也是深度用户。本身 Yaf 框架是非常简洁高性能的 PHP 框架。这导致很多相应的套件是没有配套的。比如:DB、图片操作、缓存、Cookie、Session 等。所以,自己就动手写了一套。

在实现 DB 层套件的时候,我要实现一个数据库连接的心跳检测。代码如下:

<?php

$host     = '127.0.0.1';
$port     = '3306';
$username = '数据库账号';
$password = '数据库密码';
$charset  = 'UTF8';
$dbname   = 'test';
$dsn      = "mysql:dbname={$dbname};host={$host};port={$port}";
$dbh      = new \PDO($dsn, $username, $password);
// MySQL操作出错,抛出异常。
$dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(\PDO::ATTR_ORACLE_NULLS, \PDO::NULL_NATURAL);
$dbh->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, FALSE);
$dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, FALSE);
// 以关联数组返回查询结果。
$dbh->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);


// 暂时 10 秒,我们去 MySQL 里面把数据库连接结束掉。
sleep(10);


try {
    $info = $dbh->getAttribute(\PDO::ATTR_SERVER_INFO);
    if (is_null($info)) {
        echo "---MySQL server has gone away\n";
    } else {
        echo "MySQL 连接有效\n";
    }

} catch(\Exception $e) {
    echo "ErrorCode:" . $e->getCode() . ",ErrorMsg:" . $e->getMessage();
}

这代码很简单。我就是连接成功之后,模拟 MySQL 服务器主动断掉客户端连接的异常情况。

结果会得到如下结果:

PHP Warning:  PDO::getAttribute(): MySQL server has gone away in /data/web/myself/test/test.php on line 24

Warning: PDO::getAttribute(): MySQL server has gone away in /data/web/myself/test/test.php on line 24
ErrorCode:HY000,ErrorMsg:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

可以清晰看到,我们异常是捕获到了。但是,同时也会有一个触发一个 PHP Warnning 的警告错误。而我在 Yaf 框架里面又对 PHP 各种错误进行了捕获然后记录日志并退出当前执行的程序。

当时,我以为 PDO 的属性设置这一行代码没有效果呢?
如下:

$dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

这句代码的意思是所有的数据库错误以异常模式返回。

实际上已经生效了。

我的处理方案很简单。在 set_error_handler() 设置的回调方法里面忽略这个错误即可。

博主 2011 年创建了一个《PHP 初学者官方群》,目前群成员 500 人左右。群号:168159147。为了防止广告,设置为付费入群。欢迎大家加入讨论技术!

标签: 无

发表评论: