Error with Doctrine and Laminas: driverClass has to implement the Doctrine\DBAL\Driver interface

288 Views Asked by At

I recently upgraded a Laminas project from doctrine-migrations 1.4 to 3.6 and doctrine-orm-module from 1 to 5.3. On my deployment server, when running ./vendor/bin/doctrine-module sync-metadata-storage, I receive the following error:

Fatal error: Uncaught Doctrine\DBAL\Exception: The given 'driverClass' Doctrine\DBAL\Driver\PDO\MySql\Driver has to implement the Doctrine\DBAL\Driver interface. in /var/www/vendor/doctrine/dbal/src/Exception.php:98
Stack trace:
#0 /var/www/vendor/doctrine/dbal/src/DriverManager.php(229): Doctrine\DBAL\Exception::invalidDriverClass('Doctrine\\DBAL\\D...')
#1 /var/www/vendor/doctrine/dbal/src/DriverManager.php(185): Doctrine\DBAL\DriverManager::createDriver(NULL, 'Doctrine\\DBAL\\D...')
#2 /var/www/vendor/doctrine/doctrine-orm-module/src/Service/DBALConnectionFactory.php(62): Doctrine\DBAL\DriverManager::getConnection(Array, Object(Doctrine\ORM\Configuration), Object(Doctrine\Common\EventManager))
#3 /var/www/vendor/doctrine/doctrine-module/src/ServiceFactory/AbstractDoctrineServiceFactory.php(41): DoctrineORMModule\Service\DBALConnectionFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.connec...')
#4 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(620): DoctrineModule\ServiceFactory\AbstractDoctrineServiceFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.connec...', NULL)
#5 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.connec...')
#6 /var/www/vendor/doctrine/doctrine-orm-module/src/Service/RunSqlCommandFactory.php(20): Laminas\ServiceManager\ServiceManager->get('doctrine.connec...')
#7 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(620): DoctrineORMModule\Service\RunSqlCommandFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.dbal_c...', NULL)
#8 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.dbal_c...')
#9 /var/www/vendor/doctrine/doctrine-orm-module/src/CliConfigurator.php(81): Laminas\ServiceManager\ServiceManager->get('doctrine.dbal_c...')
#10 /var/www/vendor/doctrine/doctrine-orm-module/src/Module.php(39): DoctrineORMModule\CliConfigurator->configure(Object(Symfony\Component\Console\Application))
#11 /var/www/vendor/laminas/laminas-eventmanager/src/EventManager.php(320): DoctrineORMModule\Module::DoctrineORMModule\{closure}(Object(Laminas\EventManager\Event))
#12 /var/www/vendor/laminas/laminas-eventmanager/src/EventManager.php(143): Laminas\EventManager\EventManager->triggerListeners(Object(Laminas\EventManager\Event))
#13 /var/www/vendor/doctrine/doctrine-module/src/Service/CliFactory.php(52): Laminas\EventManager\EventManager->trigger('loadCli.post', Object(Symfony\Component\Console\Application), Array)
#14 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(620): DoctrineModule\Service\CliFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.cli', NULL)
#15 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.cli')
#16 /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module.php(44): Laminas\ServiceManager\ServiceManager->get('doctrine.cli')
#17 /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module(4): include('/var/www/vendor...')
#18 /var/www/vendor/bin/doctrine-module(120): include('/var/www/vendor...')
#19 {main}
Next Laminas\ServiceManager\Exception\ServiceNotCreatedException: Service with name "doctrine.connection.orm_default" could not be created. Reason: The given 'driverClass' Doctrine\DBAL\Driver\PDO\MySql\Driver has to implement the Doctrine\DBAL\Driver interface. in /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php:627
Stack trace:
#0 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.connec...')
#1 /var/www/vendor/doctrine/doctrine-orm-module/src/Service/RunSqlCommandFactory.php(20): Laminas\ServiceManager\ServiceManager->get('doctrine.connec...')
#2 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(620): DoctrineORMModule\Service\RunSqlCommandFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.dbal_c...', NULL)
#3 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.dbal_c...')
#4 /var/www/vendor/doctrine/doctrine-orm-module/src/CliConfigurator.php(81): Laminas\ServiceManager\ServiceManager->get('doctrine.dbal_c...')
#5 /var/www/vendor/doctrine/doctrine-orm-module/src/Module.php(39): DoctrineORMModule\CliConfigurator->configure(Object(Symfony\Component\Console\Application))
#6 /var/www/vendor/laminas/laminas-eventmanager/src/EventManager.php(320): DoctrineORMModule\Module::DoctrineORMModule\{closure}(Object(Laminas\EventManager\Event))
#7 /var/www/vendor/laminas/laminas-eventmanager/src/EventManager.php(143): Laminas\EventManager\EventManager->triggerListeners(Object(Laminas\EventManager\Event))
#8 /var/www/vendor/doctrine/doctrine-module/src/Service/CliFactory.php(52): Laminas\EventManager\EventManager->trigger('loadCli.post', Object(Symfony\Component\Console\Application), Array)
#9 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(620): DoctrineModule\Service\CliFactory->__invoke(Object(Laminas\ServiceManager\ServiceManager), 'doctrine.cli', NULL)
#10 /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php(242): Laminas\ServiceManager\ServiceManager->doCreate('doctrine.cli')
#11 /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module.php(44): Laminas\ServiceManager\ServiceManager->get('doctrine.cli')
#12 /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module(4): include('/var/www/vendor...')
#13 /var/www/vendor/bin/doctrine-module(120): include('/var/www/vendor...')
#14 {main}
  thrown in /var/www/vendor/laminas/laminas-servicemanager/src/ServiceManager.php on line 627

The odd thing is that this issue doesn't occur on my local machine, with the same composer.json setup. Both systems are using the same PHP version and extensions.

I've tried the typical debugging steps, including clearing various caches, deleting the vendor directories and composer.lock files, and even the entire docker containers on both machines ensuring matching versions between environments, and checking configurations. However, I'm still unable to resolve the issue.

Any hints would be greatly appreciated.

2

There are 2 best solutions below

1
Kargpfen On BEST ANSWER

You have to Write MySQL with big Q and L:

So your driver-class must be this line:

'driverClass' => 'Doctrine\DBAL\Driver\PDO\MySQL\Driver',

2
VonC On

PDO\MySql\Driver? Check first, in your Doctrine configuration file (often located in a config directory) that the 'driverClass' parameter is correctly set. Possibly to Doctrine\DBAL\Driver\PDOMySql\Driver instead, a class that implements the Doctrine\DBAL\Driver interface.

'doctrine' => [
    'connection' => [
        'orm_default' => [
            'driverClass' => Doctrine\DBAL\Driver\PDOMySql\Driver::class,
        ],
    ],
],

Then clear the Doctrine cache to ensure that the old configurations are not being used, and regenerate the Composer autoload files to make sure that all the classes are properly autoloaded:

./vendor/bin/doctrine-module orm:clear-cache:metadata
composer dump-autoload

As in "artisan migration error "Class 'Doctrine\\DBAL\\Driver\\PDOMySql\\Driver' not found", check your doctrine/dbal version.


The Driver class exists (in accordance with the error message).
The doctrine namespace structure apparently has changed at some point, so that now, it really is Doctrine\DBAL\Driver\PDO\MySQL\Driver (instead of ...\PDOMySQL\...).
PDO\MySql\Driver -> extends DBAL\Driver\AbstractMySQLDriver -> implements DBAL\Driver\VersionAwarePlatformDriver -> extends DBAL\Driver.

Clearing the metadata cache unfortunately didn't help, either.

Then you would need to debug code directly in the Doctrine and Laminas vendor classes where the exception is being thrown to trace what exactly is going wrong. That is a bit more advanced and requires understanding of the Doctrine internals but might be necessary to diagnose the issue.
And/or modify the error and exception handlers temporarily to get a more detailed stack trace and to find out what the exact issue is.

In some scenarios, it might be worth trying to create a namespace alias in your bootstrap file to ensure that Doctrine is correctly recognizing the driver class. That is generally not recommended but might help in diagnosing the issue. Example:

class_alias('Doctrine\DBAL\Driver\PDO\MySQL\Driver', 'Doctrine\DBAL\Driver');