Search code examples
phppdoclone

How to clone PDO object safely?


I try to clone a PDO instance using $pdo2 = clone $pdo, but I get unexpected behaviour in some PHP versions:

  • The error occurs when the cloned object is used in PHP ≥ 7.
  • The PDO attributes are linked between the original and the cloned object in HHVM.
  • Everything is OK in PHP 5.

Here is a code that reproduces the problem:

$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

Is there any way to make an independent copy of a PDO object or at least copy only the DSN, username and password?

Why I need to clone a PDO instance: I need to keep a PDO instance isolated to reach goals:

  • Modifying the cloned instance doesn't change the original instance.
  • Modifying the original instance doesn't change the cloned instance.

Solution

  • There is no way to clone a PDO object safely. You should never have such an idea, as it makes no sense:

    • if you want another instance to share the same database connection, then it cannot be isolated by definition. Another instance can set distinct SQL modes, start transactions, close the connection after all.
    • if you want another instance to create another database connection, then it makes no sense to clone - just create a new one.

    So if you want an isolated PDO instance, just create it.