答案是pdo_mysql扩展未启用导致new pdo()报“could not find driver”,需确保php.ini中启用extension=pdo_mysql.so(linux/macos)或php_pdo_mysql.dll(windows),且php -m同时显示pdo和pdo_mysql。

pdo_mysql扩展没启用,new PDO()直接报“could not find driver”
PHP 8.5.5 已彻底移除旧的 ext/mysql,mysqli 虽可用但不是 PDO 的底层驱动;PDO 必须搭配 pdo_mysql 才能工作。不启用就调用 new PDO(),会立刻抛出 PDOException: could not find driver。
检查方式:php -m | grep pdo 输出必须同时含 pdo 和 pdo_mysql。若缺失:
- Linux/macOS:在
php.ini中确认有extension=pdo_mysql - Windows:确认
php_pdo_mysql.dll存在且php.ini启用了对应行 - Docker(如
php:8.5-cli):构建时需显式安装,例如RUN docker-php-ext-install pdo_mysql
DSN里漏写 charset=utf8mb4,中文和emoji存不进去还查不到错
MySQL 默认字符集是 latin1,DSN 不显式声明 charset=utf8mb4,连接看似成功,但后续 INSERT 或 SELECT 会静默截断中文、拒绝 emoji,或报 Incorrect string value —— 错误不在连接阶段,排查成本高。
正确写法示例:$dsn = "mysql:host=localhost;dbname=testdb;charset=utf8mb4"
- 别写
utf8:MySQL 的utf8实际是utf8mb3,不支持 4 字节 Unicode - 即使 MySQL 配置了
collation-server = utf8mb4_unicode_ci,DSN 仍必须写charset=utf8mb4—— PDO 不读服务端默认值 -
SET NAMES utf8mb4是冗余操作,不能替代 DSN 中的声明
密码含 @、/、: 等字符,DSN 解析错位
DSN 是 URL 风格字符串,密码里的特殊字符会导致解析失败。例如密码是 pa@ss/word,不转义直接拼进 DSN:mysql:host=localhost;dbname=test;user=admin;password=pa@ss/word,PDO 会把 @ 当作 host 分隔符,误判主机为 ss/word。
- 必须对密码单独调用
urlencode($password),再拼入 DSN - 空密码要传
""(空字符串),不能传null,否则触发TypeError - 不要把密码硬编码进 DSN 字符串拼接,比如
"password={$pass}"—— 极易因未转义崩掉
安全写法:
$dsn = "mysql:host={$host};dbname={$db};charset=utf8mb4";<br>$pdo = new PDO($dsn, $user, urlencode($pass));
PDO默认不抛异常,错误被静默吞掉
new PDO() 成功后,PDO::query()、PDO::prepare() 等方法默认只返回 false 表示失败,不抛异常。这意味着表不存在、字段名写错、SQL 语法错误等,都可能悄无声息地返回 false,而你还在那儿查数据为空的原因。
- 必须在连接后立即设置:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) - 配合
try-catch才能捕获真实错误,比如SQLSTATE[42S02]: Base table or view not found - 不设这个属性,调试时几乎等于盲操作
最常被忽略的是密码转义和 charset=utf8mb4 的强制声明——这两点不出问题时一切正常,一出就是线上数据损坏或用户投诉乱码,且错误日志里找不到源头。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











