Dbal: driver_class not working when using url connection parameter

Created on 7 Jul 2018  路  8Comments  路  Source: doctrine/dbal

Bug Report

| Q | A
|------------ | ------
| BC Break | no
| Version | 2.7.1

Summary


While using complete url parameter to connect to database, I can't use a custom driver class.
I need to use all parameters (host, port, dbname, user, password).

Current behavior


driver_class only works if all connection parameters are defined.

How to reproduce


Clone symfony/demo project, use this workaround to create a custom driver.

Add something like this to the driver:

public function getDatabasePlatform()
{
    echo "Should be displayed";
    exit;

    return new Platform();
}

Then run bin/console doctrine:fixtures:load --purge-with-truncate --> The text should not appear.
Remove DATABASE_URL and use every parameters separately:

doctrine:
    dbal:
       host: 127.0.0.1
       port: 3306
       dbname: symfony
       user: root
       password: 123456

Then the text should appear.

Expected behavior


A custom driver_class must be working when using url parameter.

I'll have a look if I can find something, but I lost a lot of time on this strange behavior.

All 8 comments

I found the cause: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/DriverManager.php#L403

But why? Is there no way to use a custom driver with url parameter?

@thomas-hiron I'm not sure why it's implemented this way. From what I understand, the driver is only used to determine the driver_class. If that's the case, they should be mutually exclusive.

In the meanwhile, could you try using a URI without the scheme? Like the following:
```php
$url = '//user:[email protected]/path?param=value';
var_dump(parse_url($url));

/*
array(5) {
'host' =>
string(11) "example.com"
'user' =>
string(4) "user"
'pass' =>
string(8) "password"
'path' =>
string(5) "/path"
'query' =>
string(11) "param=value"
}
*/

Yes it is working without the scheme! Should I create a PR to update the doc or wait for more comments to know what to do?

I think this behavior is too confusing to be just documented. Unless there are some reasons I'm not aware of, the correct behavior should either of:

  1. driver_class overrides driver as the former is more specific.
  2. One and only one of driver_class and driver is allowed to be specified since otherwise, they can be controversial.

@Ocramius any idea why the current behavior is implemented this way?

Any updates on this?

After a long period of time, mysql server can go away. This packages (https://github.com/facile-it/doctrine-mysql-come-back) is a wrapper around the doctrine driver to reconnect if it went away. I've been looking for solutions to overwrite driver class (override mapping of pdo_mysql, add driver to $_driverMap, specify driver_class, ... but none of them worked/is possible).

any update?

For using custom DBAL Driver for Symfony 4/6 set the driver_class: App\DBAL\Driver in doctrine.yaml and very important, don't use url in doctrine.yaml and set:

    # url: '%env(resolve:DATABASE_URL)%'
    # IMPORTANT: You MUST configure your server version,
    # either here or in the DATABASE_URL env var (see .env file)
    #server_version: '5.7'
    dbname: db_name
    host: db_host
    user: db_user
    password: db_password
    driver: pdo_mysql
    driver_class: App\DBAL\Driver
Was this page helpful?
0 / 5 - 0 ratings