How to get PDO connection in cake 5

With the cake/database module version ^4 I was able to add the PDO connection container definition with the getConnection() method like this:

PDO::class => function (ContainerInterface $container) {
    $connection = $container->get(Connection::class);
    $connection->getDriver()->connect();
    return $connection->getDriver()->getConnection(); // Returned instance of \PDO
},

In Cake 5 database, this function doesn’t exist any more, but there is getPdo() that returns the PDO connection instance. The issue is that it’s protected meaning I can’t access it in my container definition.

Entire function

// Line 239
protected function getPdo(): PDO
{
    if ($this->pdo === null) {
        $this->connect();
    }
    assert($this->pdo !== null);
    return $this->pdo;
}

How can I access the PDO connection directly? If there is no other way, would it make sense to change the visibility scope from protected to public? I need it for my integration testing environment.

Thanks in advance for your precious help.

We discussed this in Update property and methods for better readability. by ADmad · Pull Request #16351 · cakephp/cakephp · GitHub

You can still directly execute sql via the Driver::exec method if you require that.

Otherwise you can also adjust the accessibility of methods and properties via reflection inside your tests if you really need it like you can see here: https://github.com/cakephp/cakephp/blob/5.x/tests/TestCase/Database/ConnectionTest.php#L1114

1 Like
    public static function dbh()
    {

        try {
            $dbh = ConnectionManager::get('default');
            return $dbh;
        } catch (PDOException $e) {
            throw new pdoDbException($e);
        }
    }

Thank you guys a lot for the answers. I solved it by setting the getPdo method to accessible via the ReflectionClass like this:

PDO::class => function (ContainerInterface $container) {
    $driver = $container->get(Connection::class)->getDriver();
    $class = new ReflectionClass($driver);
    $method = $class->getMethod('getPdo');
    $method->setAccessible(true);
    return $method->invoke($driver);
},