当我使用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)?
作为实现两者的人,我可以告诉你,原因是通过将字符串按原样传递给Postgres(和ODBC),这些数据库的PDO驱动程序代码不需要更新,因为基础库添加了新功能。
由于MySQL没有自己的连接字符串解析代码,我们发明了一种将数据传递到底层MySQL函数调用的机制,该函数具有非常固定的参数API。
没有意外;这是非常故意的。
是的,此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脚,但是很简单而且有效。
这个问题已有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);
}
}