You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP命令行运行PDO报MySQL访问拒绝错误 但Apache环境下正常

CLI 环境下 PDO 连接 MySQL 报 1045 错误的排查方案

适用场景:同套代码在Apache Web环境下连接数据库正常,MySQL命令行工具可正常连接,所有数据库用户在CLI执行时统一抛出SQLSTATE[HY000] [1045] Access denied错误,已排除凭据错误、服务端权限配置问题。

最高发原因:PHP CLI 与 Apache 的 socket 配置不匹配

  • 当PDO的DSN配置host为localhost时,连接不会走TCP协议,而是直接读取PHP配置里的pdo_mysql.default_socket参数值,通过Unix本地socket和MySQL通信。
  • 快速核对步骤:
    • CLI下执行php -i | grep pdo_mysql.default_socket,拿到CLI实际生效的socket路径
    • 执行mysql_config --socket拿到MySQL服务实际监听的socket路径
    • 对比两个路径是否完全一致。

Ubuntu系统更新OpenSSL相关依赖时,往往会顺带升级PHP的deb安装包,容易出现CLI侧加载的php.ini指向其他版本配置文件的问题,导致socket路径和MySQL实际监听路径不匹配。此时PDO尝试连接错误socket时,MySQL服务会直接返回1045权限拒绝,而非socket文件不存在的报错,和该场景的现象完全吻合。

  • 验证方法:临时修改DSN为socket直连模式,格式为mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=dbname;charset=utf8,如果连接成功,即可确认是socket配置不匹配问题。
  • 解决方式:将CLI侧php.ini里的pdo_mysql.default_socket值修改为MySQL实际的socket路径,无需重启MySQL,下次执行CLI脚本即可生效。

次高发原因:环境变量干扰

  • CRON执行环境的变量加载逻辑和交互式Shell、Apache完全独立,容易残留历史配置的环境变量:
    • 如果环境中存在MYSQL_PWD变量,PDO依赖的libmysqlclient库会优先读取该值作为连接密码,直接覆盖代码里传入的密码参数,导致认证失败。
    • 同时检查是否存在MYSQL_HOST类变量,会自动覆盖DSN里配置的host参数。
  • 验证方法:执行CLI命令前清空全量环境变量,运行env -i PATH=$PATH php dispatchCLI.php task=first,如果连接恢复正常,即可确认是环境变量干扰。
  • 解决方式:在CRON任务脚本开头清空相关的MySQL环境变量,或修正过期的变量值。

OpenSSL升级关联的兼容问题

  • 系统更新OpenSSL时会触发依赖链更新,容易导致PHP pdo_mysql扩展动态链接的libmysqlclient版本发生偏移,出现密码认证握手不兼容的问题,表现为固定的1045错误,无明确握手失败提示。
  • 验证方法:临时在PDO连接选项里关闭SSL证书校验,设置PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,同时临时关闭服务端的强制SSL连接配置,测试是否可正常连接。
  • 解决方式:通过apt reinstall php-mysql命令重装对应版本的扩展包,让扩展链接的libmysqlclient版本和当前系统环境对齐。

无需浪费时间排查的方向

  • 不用反复核对数据库用户的权限配置:同套代码在Apache环境下已经可以正常连接,说明服务端的账号、授权规则没有问题,CLI侧的报错完全是客户端连接层的问题。
  • 不用纠结DSN里把localhost改成127.0.0.1无效的问题:socket、环境变量、库版本的问题会同时影响TCP和socket两种连接模式,不是host名配置的问题。

内容的提问来源于stack exchange,提问作者faelv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 04:06:03