【问题标题】:How to clone PDO object safely?如何安全地克隆 PDO 对象?
【发布时间】:2017-10-25 02:42:53
【问题描述】:

我尝试使用 $pdo2 = clone $pdo 克隆 PDO 实例,但在某些 PHP 版本中出现意外行为:

  • 克隆对象在PHP ≥ 7中使用时出现错误。
  • PDO 属性链接在 HHVM 中的原始对象和克隆对象之间。
  • 在 PHP 5 中一切正常。

这是重现问题的代码:

$pdo1 = new \PDO('sqlite::memory:');
$pdo1->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
echo "PDO 1 is OK\n";

$pdo2 = clone $pdo1;
$pdo2->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING);
echo "PDO 2 is OK\n";

echo $pdo1->getAttribute(\PDO::ATTR_ERRMODE) === $pdo2->getAttribute(\PDO::ATTR_ERRMODE)
    ? "❌ The attribute IS changed\n"
    : "✅ The attribute IS NOT changed\n";

Live demo

有没有办法制作一个 PDO 对象的独立副本,或者至少只复制 dns、用户名和密码?

为什么我需要克隆 PDO 实例:我需要保持 PDO 实例隔离以达到目标:

  • 修改保留的实例不会改变原始实例。
  • 修改原始实例不会更改保留的实例。

【问题讨论】:

  • 为什么不能在数据库中打开新的 PDO 资源?克隆像资源一样的对象是有问题的。
  • @BillKarwin 我可以在构建项目时。但是我制作了一个尽可能坚固的库。 PDO 实例是一个依赖项。更改 PDO 实例的可能性会降低库的可靠性。
  • 如果无法克隆 PDO,我只会要求用户传递 PDO 构造函数参数而不是 PDO 对象,并在库中创建 PDO 实例。

标签: php pdo clone


【解决方案1】:

没有办法安全地克隆 PDO 对象。你永远不应该有这样的想法,因为它没有意义:

  • 如果你想让另一个实例共享同一个数据库连接,那么它不能被定义隔离。毕竟,另一个实例可以设置不同的 SQL 模式、启动事务、关闭连接
  • 如果您希望另一个实例创建另一个数据库连接,那么克隆没有意义 - 只需创建一个新实例。

因此,如果您想要一个独立的 PDO 实例,只需创建它即可。

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 2012-11-17
    • 2010-09-07
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    相关资源
    最近更新 更多