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

问题描述 投票:32回答:3

当我使用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)?

php mysql postgresql pdo
3个回答
89
投票

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

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

没有意外;这是非常故意的。


3
投票

是的,此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

有点la脚,但是很简单而且有效。


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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.