phpenv下需启用php_pdo.dll和php_pdo_mysql.dll扩展,dsn须用127.0.0.1:3306+utf8mb4,密码为空,连接后应校验select 1,事务前检测连接状态。

phpEnv 是 Windows 下轻量级 PHP 开发环境,自带 Apache + MySQL + PHP,但默认不启用 PDO 扩展、不配置数据库连接参数——直接 new PDO 会报 Class 'PDO' not found 或 SQLSTATE[HY000] [1045] Access denied,不是代码写错了,而是环境没调通。
确认 phpEnv 中 PDO 扩展已启用
phpEnv 界面右下角托盘图标 →「PHP 设置」→「PHP 扩展」→ 勾选 php_pdo.dll 和 php_pdo_mysql.dll(注意:不是 php_mysqli.dll)→ 点击「应用」重启 Apache。验证方式:新建 phpinfo.php 放入 www 目录,访问后搜索「pdo」和「mysql」,必须同时出现「PDO Driver for MySQL」且状态为 enabled。
常见错误现象:Call to undefined function pdo_connect() 或 Class 'PDO' not found,90% 是这一步漏了;即使写了 extension=php_pdo_mysql.dll 在 php.ini 里,phpEnv 的 GUI 管理器会覆盖手动修改,必须用界面勾选。
封装类必须适配 phpEnv 默认 MySQL 配置
phpEnv 自带的 MySQL 默认账号是 root,密码为空(不是 123456 或 root),端口为 3306,字符集推荐 utf8mb4。封装类中 DSN 字符串若写成 mysql:host=localhost;dbname=test 可能失败,因为 phpEnv 的 MySQL 绑定的是 127.0.0.1 而非 localhost(Windows 下 localhost 会走命名管道,而 phpEnv 的 MySQL 未启用)。
实操建议:
- DSN 必须用
mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8mb4,不要省略port和charset - 连接选项中必须显式设置
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,否则错误静默,调试困难 - 避免使用
PDO::ATTR_PERSISTENT => true,phpEnv 是本地开发环境,持久连接反而易触发MySQL server has gone away
封装类中避免硬编码,从 phpEnv 配置文件读取参数
phpEnv 安装目录下有 php\conf\php.ini 和 mysql\my.ini,但封装类不应去解析 ini 文件——推荐在项目根目录放一个 config.local.php,内容如下:
<?php return [
'db' => [
'host' => '127.0.0.1',
'port' => 3306,
'dbname' => 'test',
'user' => 'root',
'pass' => '',
'charset' => 'utf8mb4',
],
];
封装类构造时 require_once __DIR__ . '/config.local.php',再拼 DSN。这样换机器或部署到其他环境时,只改这个文件,不碰类代码。
容易踩的坑:
- 把密码写进类里,提交 Git 后泄露;
config.local.php应加入.gitignore - 用
getenv()读环境变量——phpEnv 不自动注入,得手动改 Apache 的httpd.conf,没必要 - 连接后不测试连通性,直到第一个查询才报错;建议在构造函数末尾加
$this->pdo->query("SELECT 1")->fetchColumn()
事务嵌套在 phpEnv 下要小心超时
phpEnv 自带的 MySQL 配置中 wait_timeout 默认是 28800 秒(8 小时),看似够用,但本地开发常长时间不操作,连接空闲后被 MySQL 主动断开,此时再 commit() 就会抛 PDOException: MySQL server has gone away。
解决方案不是调大 timeout,而是封装层主动检测:
- 每次执行前检查
$this->pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS)是否包含Connection OK - 或更简单:在
beginTransaction()前先执行一条SELECT 1,失败则重建连接 - 不建议在封装类里自动重连,会掩盖逻辑错误;应让开发者明确感知连接中断并处理
真正麻烦的不是连不上,而是事务开启后中间 sleep(10) 再 commit —— 这种写法在 phpEnv 下极易出错,但线上环境未必复现,本地测试必须覆盖空闲场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











