PDO 连接测试

Posted

技术标签:

【中文标题】PDO 连接测试【英文标题】:PDO Connection Test 【发布时间】:2011-09-09 22:39:27 【问题描述】:

我正在为我的一个应用程序编写安装程序,我希望能够测试一些默认数据库设置。

这是否可以使用 PDO 来测试有效和无效的数据库连接?

我有以下代码:

try
            $dbh = new pdo('mysql:host=127.0.0.1:3308;dbname=axpdb','admin','1234');
            die(json_encode(array('outcome' => true)));
        catch(PDOException $ex)
            die(json_encode(array(
                'outcome' => false,
                'message' => 'Unable to connect'
            )));
        

我遇到的问题是脚本尝试连接,直到脚本执行时间 60 秒用完,而不是说它无法连接到数据库。

谢谢

【问题讨论】:

$dbh = new PDO ?其他一切对我来说都很好。 小写 pdo 的工作方式与 PDO 相同,如果我在脚本中输入正确的详细信息,则按预期工作,但我正在尝试检测无效设置 您是否尝试添加选项PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 如果我在这里添加它:$dbh = new PDO('mysql:host=127.0.0.1;port=3308;dbname=axpdb','admin','1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); 它没有区别,因为这是我不能在下面$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); 做的错误 【参考方案1】:

连接数据库时需要设置错误模式:

try
    $dbh = new pdo( 'mysql:host=127.0.0.1:3308;dbname=axpdb',
                    'admin',
                    '1234',
                    array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    die(json_encode(array('outcome' => true)));

catch(PDOException $ex)
    die(json_encode(array('outcome' => false, 'message' => 'Unable to connect')));

欲了解更多信息,请参阅以下链接:

Using MySQL with PDO

Errors and error handling

【讨论】:

结合ini_set('display_errors', 'off'); 工作正常。谢谢 @Themodem:为什么需要关闭显示错误?你已经发现了异常——它已经被处理了。 @Mark,因为PDO::ERRMODE_EXCEPTION 的实现被破坏了(php5.3.28),并且在某些情况下没有效果(例如,我的主机上的“数据库服务器未运行”)。因此,不幸的是,这个解决方案还不够,因为 Themodem 在他的解决方法中注意到了这一点。 (嘿,顺便说一句,只需输入@new pdo(),不要为了这个而将display_errors 暴力破解为off!) 例如:Warning: PDO::__construct() [pdo.--construct]: [2002] No connection could be made because the target machine actively refused it. (trying to connect via tcp://localhost:3306) in ...,代码为:$this->pdo = new PDO($cfg['DB'], $cfg['DB_USER'], $cfg['DB_PASS'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_LOCAL_INFILE => true));(注意:异常抛出的,咳咳,我在catch子句中放了一些日志信息.)【参考方案2】:

正如@Sascha Galley 已经提到的,您应该将错误模式设置为异常模式。但是,您还应该设置PDO::ATTR_TIMEOUT 属性以防止在某些情况下长时间等待响应。

虽然文档说此属性的行为在 MySQL 的情况下取决于驱动程序,但它是连接超时。你不会找到任何关于它的documentation,但这里有一个来自驱动程序源代码的简短 sn-p:

long connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);

【讨论】:

【参考方案3】:

如所见,例如在this answer 的 cmets 中(但几乎没有其他任何地方,所以我在这里让它更加明显),“经典”PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 解决方案并不总是有效

PDO::ERRMODE_EXCEPTIONis broken的实现,所以在某些情况下似乎“泄露”了。

例如:

警告: PDO::__construct() [pdo.--construct]: [2002] 由于目标机器主动拒绝,无法建立连接 它。 (尝试通过 tcp://localhost:3306 连接) [...] db.php 上线 34

那里的代码:

try 
    $this->pdo = new PDO($cfg['DB'], $cfg['DB_USER'], $cfg['DB_PASS'],
        array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
 catch 
    echo("Can't open the database.");

抛出异常(咳咳:我可以看到我的消息)。

因此,作为必要的解决方法,您需要还添加一个@ (在这种情况下我们称之为“尿布操作员”) 之前new pdo(...) 实际保持清洁。

【讨论】:

【参考方案4】:

PDO::ERRMODE_EXCEPTION 末尾缺少右括号。

应该是:

$this->pdo = new PDO($cfg['DB'], $cfg['DB_USER'], $cfg['DB_PASS'],
    array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

【讨论】:

以上是关于PDO 连接测试的主要内容,如果未能解决你的问题,请参考以下文章

php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例

数据库: PHP使用PDO连接数据库实现增 删 改 查 操作

正式环境数据迁移到测试环境及测试环境LAMP搭建

具有扩展 PDOStatement 的 PDO 在设置为 NULL 时无法断开连接

PDO产品测试

如何将 MySQLi 连接器转换为 PHP PDO