使用Docker构建LEMP栈时PDO默认SQLite驱动切换MySQL驱动问题
嘿,我之前也碰到过一模一样的情况——明明没装SQLite,phpinfo()里却显示它存在,而且PDO默认就用它。其实这是因为官方PHP-FPM镜像默认就把SQLite的PDO驱动编译进去了,它属于PHP核心关联的轻量组件,不用手动安装也会存在。下面一步步帮你把默认驱动改成MySQL:
1. 先确保MySQL PDO扩展已经正确安装
官方PHP-FPM镜像默认是不带pdo_mysql扩展的,所以必须在你的Dockerfile里明确安装它:
如果是用基于Debian的PHP镜像(比如php:8.2-fpm),直接加这行:
RUN docker-php-ext-install pdo_mysql
如果是Alpine版本的镜像,得先装依赖包:
RUN apk add --no-cache mysql-dev \ && docker-php-ext-install pdo_mysql
这里用docker-php-ext-install是官方提供的专用脚本,能自动处理扩展的编译和配置,比手动编译靠谱多了。
2. 修改PHP配置强制指定PDO默认驱动
就算装了pdo_mysql,PHP还是会默认用SQLite,所以得在PHP配置里明确指定默认驱动:
新建一个配置文件(比如pdo.ini),内容如下:
; 把PDO默认驱动设置为mysql pdo.default_driver = mysql
然后把这个配置文件挂载或复制到PHP-FPM容器的配置目录里。比如在Dockerfile里加:
# 假设你的配置文件在项目根目录的php-conf.d文件夹下 COPY php-conf.d/ /usr/local/etc/php/conf.d/
这样PHP启动时会自动加载这个配置,覆盖默认的SQLite驱动设置。
3. 检查Docker Compose的MySQL关联配置
确保你的PHP-FPM服务能正常访问MySQL服务,环境变量也配置正确,示例Compose配置:
services: php-fpm: build: . environment: - DB_HOST=mysql # 和下面的MySQL服务名一致 - DB_NAME=your_database_name - DB_USER=root - DB_PASSWORD=your_mysql_root_password depends_on: - mysql mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=your_mysql_root_password - MYSQL_DATABASE=your_database_name
注意depends_on只是保证MySQL先启动,最好在你的应用里加个连接重试逻辑,或者用wait-for-it脚本确保MySQL完全就绪后再启动PHP-FPM,避免连接失败。
4. 验证配置是否生效
启动容器后,进入PHP-FPM容器执行命令验证:
# 查看已加载的PDO扩展 php -m | grep pdo
输出应该包含pdo_mysql和pdo_sqlite(SQLite还是会存在,但我们已经改了默认驱动)。再执行:
php -r "echo 'Available PDO drivers: ' . implode(', ', PDO::getAvailableDrivers()) . PHP_EOL; echo 'Default PDO driver: ' . ini_get('pdo.default_driver') . PHP_EOL;"
如果输出里的Default PDO driver是mysql,就说明配置生效了。
额外排查点
- 如果还是没生效,去phpinfo()里看
Loaded Configuration File和Additional .ini files parsed,确认我们的pdo.ini被正确加载了。 - 如果你用了框架(比如Laravel、Symfony),还要检查框架的配置文件,确保数据库驱动设置的是
mysql,比如Laravel的.env里要设置DB_CONNECTION=mysql。
内容的提问来源于stack exchange,提问作者twigg

