Why is PHP PDO DSN a different format for MySQL versus PostgreSQL? Why is PHP PDO DSN a different format for MySQL versus PostgreSQL? postgresql postgresql

Why is PHP PDO DSN a different format for MySQL versus PostgreSQL?


As the person that implemented both, I can tell you that the reason is that by passing the string through as-is to postgres (and ODBC) the PDO driver code for those databases does not need to be updated as the underlying library adds new features.

Since MySQL does not have its own connection string parsing code, we invented a mechanism for passing data in to the underlying MySQL function calls, which have a very specific API with fixed parameters.

No accident; it's very deliberate.


This has been resolved in PHP 7.4, as can be seen in the new features.

I have confirmed it locally that we can write:

$dbh = new PDO('mysql:host=localhost;dbname=my_db;charset=utf8mb4;user=root;password=')


Yep, this API inconsistency is a major annoyance.

As a work-around, I pack the actual DSN string with an optional username and password using query-string syntax - then parse and construct like this:

parse_str($connection_string, $params);$pdo = new PDO($params['dsn'], @$params['username'], @$params['password']);

So for PostgreSQL, use a $connection_string like:

dsn=pgsql:host=localhost;dbname=test;user=root;password=root

And for MySQL, use a string like:

dsn=mysql:host=localhost;dbname=testdb&username=root&password=root

Kind of lame, but it's simple and it works.