【发布时间】:2014-06-19 16:31:45
【问题描述】:
我目前正在重构我的 PHP 框架的数据库包装类以使用 PDO。
我有几项主要任务必须使用数据库包装类完成:
- 针对 MySQL、PostgreSQL 和 Oracle 数据库的基本 DML 操作(INSERT、SELECT、UPDATE、DELETE)总是完全相同的结果
- 仅持久连接(Oracle 不能选择每个请求的新连接,因为建立连接的成本在延迟方面非常高)
- 时刻绑定参数(提供开箱即用的SQL注入证明方法)
不幸的是,在对 MySQL 数据库执行查询时,我每次使用以下两个 PDO 属性 ATTR_EMULATE_PREPARES => FALSE 和 ATTR_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_PREPARES 或ATTR_PERSISTENT 的任何属性,它就可以正常工作。
我在我的开发机器上使用 WampServer 2.4 64 位(Apache 2.4.4、PHP 5.4.12、MySQL 5.6.12)。
有什么建议最好的解决方案(记住我必须实现的目标)?
【问题讨论】: