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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/237367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 23:36:11  来源:igfitidea点击:

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

phpmysqlpostgresqlpdo

提问by Vern Takebayashi

When I connect to a MySQL database using PDO, the way I need to connect is:

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

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

But, for PostgreSQL, the DSN is more standard (IMO):

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

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

Is there any reason why MySQL cannot use a single string? Or is this just because of the versions I am using (PHP 5.2, MySQL 5.0, PostgreSQL 8.1)?

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

回答by Wez Furlong

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.

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

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.

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

No accident; it's very deliberate.

无意外;这是非常刻意的。

回答by mindplay.dk

Yep, this API inconsistency is a major annoyance.

是的,这种 API 不一致是一个主要的烦恼。

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:

作为一种变通方法,我使用查询字符串语法将实际的 DSN 字符串与可选的用户名和密码打包 - 然后像这样解析和构造:

parse_str($connection_string, $params);

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

So for PostgreSQL, use a $connection_stringlike:

所以对于 PostgreSQL,使用$connection_string类似的:

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

And for MySQL, use a string like:

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

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

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

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

回答by Shish

This question is more than 10 years old, but I still end up here every time I create a new project that uses PDO... I'm writing my solution here so that I can save myself the trouble next time :P

这个问题已经有 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);
    }
}