【问题标题】:Disabling ATTR_EMULATE_PREPARES in combination with persistent connections results in dropped connection结合持久连接禁用 ATTR_EMULATE_PREPARES 会导致连接断开
【发布时间】:2014-06-19 16:31:45
【问题描述】:

我目前正在重构我的 PHP 框架的数据库包装类以使用 PDO。

我有几项主要任务必须使用数据库包装类完成:

  • 针对 MySQL、PostgreSQL 和 Oracle 数据库的基本 DML 操作(INSERT、SELECT、UPDATE、DELETE)总是完全相同的结果
  • 仅持久连接(Oracle 不能选择每个请求的新连接,因为建立连接的成本在延迟方面非常高)
  • 时刻绑定参数(提供开箱即用的SQL注入证明方法)

不幸的是,在对 MySQL 数据库执行查询时,我每次使用以下两个 PDO 属性 ATTR_EMULATE_PREPARES => FALSEATTR_PERSISTENT => TRUE 的组合时都会遇到“ERR_CONNECTION_RESET”。

这是示例代码(不是实际的包装类,但它重复了相同的错误):

$connection = new PDO(
    'mysql:host=localhost;dbname=test'
    ,'root'
    ,''
    ,array(
        PDO::ATTR_AUTOCOMMIT => FALSE
        ,PDO::ATTR_CASE => PDO::CASE_LOWER
        ,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ,PDO::ATTR_EMULATE_PREPARES => FALSE
        ,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        ,PDO::ATTR_PERSISTENT => TRUE
        ,PDO::ATTR_ORACLE_NULLS => PDO::NULL_EMPTY_STRING
    )
);

if (!$connection->inTransaction()) $connection->beginTransaction();

$statement = $connection->prepare('INSERT INTO dms_devices (model_id, serial_no, name, status) VALUES (:model_id, :serial_no, :name, :status)');

foreach (array('model_id' => 1, 'serial_no' => 12219321, 'name' => 'Demo', 'status' => 'DSS_MANUFACTURED') as $name => $value) {
    $statement->bindValue(':'.$name, $value);
}

$statement->execute();

$connection->commit();

一旦我注释掉ATTR_EMULATE_PREPARESATTR_PERSISTENT 的任何属性,它就可以正常工作。

我在我的开发机器上使用 WampServer 2.4 64 位(Apache 2.4.4、PHP 5.4.12、MySQL 5.6.12)。

有什么建议最好的解决方案(记住我必须实现的目标)?

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    发现这个已经注册PHP segmentation fault bug #61411了。

    不幸的是,它在 5.4.12 版本中仍未修复。

    【讨论】:

      猜你喜欢
      • 2014-09-20
      • 1970-01-01
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      相关资源
      最近更新 更多