当我使用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)?
答案 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);
}
}