为什么PHP PDO DSN与MySQL和PostgreSQL的格式不同?

时间:2008-10-26 01:52:55

标签: php mysql postgresql pdo

当我使用PDO连接到MySQL数据库时,我需要连接的方式是:

$pdoConnection = new PDO("mysql:host=hostname;dbname=databasename",user,password);

但是,对于PostgreSQL,DSN更标准(IMO):

$pdoConnection = new PDO("pgsql:host=hostname;dbname=databasename;user=username;password=thepassword");

MySQL有什么理由不能使用单个字符串吗?或者这只是因为我使用的版本(PHP 5.2,MySQL 5.0,PostgreSQL 8.1)?

4 个答案:

答案 0 :(得分:87)

作为实现这两者的人,我可以告诉你原因是通过将字符串原样传递给postgres(和ODBC),这些数据库的PDO驱动程序代码不需要作为底层库更新添加新功能。

由于MySQL没有自己的连接字符串解析代码,我们发明了一种机制,用于将数据传递给底层的MySQL函数调用,这些函数调用具有一个具有固定参数的非常特定的API。

不是偶然的;这是非常慎重的。

答案 1 :(得分:3)

这在PHP 7.4中已得到解决,如the new features所示。

我在本地确认可以写:

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

答案 2 :(得分:2)

是的,这种API的不一致是一个很大的烦恼。

作为解决方法,我使用查询字符串语法打包实际的DSN字符串以及可选的用户名和密码 - 然后解析并构造如下:

parse_str($connection_string, $params);

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

因此,对于PostgreSQL,请使用$connection_string之类的:

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

对于MySQL,请使用如下字符串:

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

有点蹩脚,但它很简单而且有效。

答案 3 :(得分:0)

这个问题已有10多年的历史了,但是每次我创建一个使用PDO的新项目时,我仍然会在这里结束...我正在这里编写解决方案,以便下次可以避免麻烦:P

class MyPDO extends PDO {
    public function __construct($dsn, $options = null) {
        $user=null;
        $pass=null;

        if (preg_match("/user=([^;]*)/", $dsn, $matches)) {
            $user=$matches[1];
        }
        if (preg_match("/password=([^;]*)/", $dsn, $matches)) {
            $pass=$matches[1];
        }

        parent::__construct($dsn, $user, $pass, $options);
    }
}