PHP 5.6无法连接MySQL服务,但Bash可正常连接问题求助
PHP PDO连接MySQL提示权限拒绝,但命令行/Workbench可正常连接的解决办法
问题背景
我最近更换了新服务器,完成文件复制和环境配置后,遇到了一个奇怪的问题:PHP通过PDO无法连接MySQL,提示权限拒绝,但用相同的账号密码通过Bash命令行或者MySQL Workbench却能正常连接。
服务器环境
- 操作系统:Ubuntu 16.04
- Web服务器:Nginx
- PHP版本:5.6
- MySQL版本:5.7.20
相关配置与代码
数据库配置文件
define("DB_HOST", "localhost"); define("DB_NAME", "zlproject"); define("DB_USER", "username"); define("DB_PASS", "password"); // 注:实际密码包含$符号 define("DB_PORT", "3306");
PDO连接脚本
public function connect() { if (!isset($this->connection)) { $this->connection = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";dbport=" . DB_PORT . ";charset=utf8", DB_USER, DB_PASS); } return $this->connection; }
错误信息
Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user 'username'@'localhost' (using password: YES)'
问题原因与解决方法
经过排查,发现问题根源在于数据库密码包含$符号:PHP会将双引号包裹的字符串中的$识别为变量标识符进行解析,导致实际传递给PDO的密码不完整(比如密码是pa$$word,PHP会把$word当作未定义变量替换为空,最终传递的密码变成pa)。
解决办法有两种:
- 用单引号包裹密码,PHP不会解析单引号字符串中的变量:
define("DB_PASS", 'pa$$word');
- 在双引号字符串中对
$进行转义,使用\$表示原义的$:
define("DB_PASS", "pa\$\$word");
修改后PDO就能正确获取完整密码,顺利连接到MySQL了。
内容的提问来源于stack exchange,提问作者L. Z.
相关产品推荐
相关产品推荐

