frankenphp默认使用frankenphp sapi而非php-fpm,导致localhost数据库连接失败;需将db_host改为docker服务名(如db),显式启用pdo_mysql扩展,并设置连接超时以适配其激进的连接回收机制。

FrankenPHP 默认用 PHP-FPM 模式连数据库会失败
FrankenPHP 启动时默认走的是 SAPI frankenphp(不是 fpm),而很多老项目在 php.ini 或连接逻辑里硬编码了 localhost:3306,结果发现 MySQL 连不上——不是端口错,是容器网络隔离导致的 localhost 解析失败。你得把数据库地址从 localhost 改成 Docker 网络里的服务名,比如 mysql 或 db。
常见错误现象:PDOException: SQLSTATE[HY000] [2002] Connection refused,或者 mysqli_connect(): (HY000/2002): Connection refused。
- 检查你的
docker-compose.yml里数据库服务名(比如services: db:→ 地址就该写db) - PHP 代码中连接字符串别再用
127.0.0.1或localhost,改用服务名 - 如果用了 Laravel,确认
.env中的DB_HOST=db,不是DB_HOST=127.0.0.1 - FrankenPHP 容器和 DB 容器必须在同一个 Docker 网络下(
networks:需显式声明或共用 default)
用 frankenphp SAPI 时 pdo_mysql 扩展必须启用
FrankenPHP 的 frankenphp SAPI 和传统 FPM 不同,它不自动加载所有扩展。如果你之前靠 FPM 的全局配置启用 pdo_mysql,迁过来后可能直接报 Class 'PDO' not found 或 Driver not found: mysql。
实操建议:
- 运行
frankenphp server --php-ini /path/to/php.ini时,确保该php.ini包含extension=pdo_mysql - 不要依赖
/usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini这类路径——FrankenPHP 不一定读它 - 用
frankenphp php -m | grep pdo验证扩展是否真加载成功 - 若用自定义 Dockerfile,记得在
RUN docker-php-ext-install pdo_mysql后显式启用(有些基础镜像需额外echo "extension=pdo_mysql" >> $PHP_INI_DIR/conf.d/pdo_mysql.ini)
mysqli 和 PDO 在 FrankenPHP 下行为一致,但连接超时更敏感
FrankenPHP 对长连接、空闲连接的回收比 FPM 更激进,尤其在使用 mysqli::real_connect() 或 PDO::__construct() 时,如果没设 PDO::ATTR_TIMEOUT 或 mysqli_options(MYSQLI_OPT_CONNECT_TIMEOUT),容易在低流量时段触发连接中断。
推荐做法:
- 显式设置连接超时:PDO 构造时加
['options' => [PDO::ATTR_TIMEOUT => 5]];mysqli 用mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 5) - 避免复用长期存活的
PDO实例——FrankenPHP 的 worker 生命周期短,连接池机制不如 FPM 成熟 - 如果用连接池中间件(如 ProxySQL),确认其健康检查频率能跟上 FrankenPHP 的 worker 启停节奏
DB_HOST 就完事,其实 php.ini 扩展加载路径、连接超时默认值、甚至 mysql.default_socket 这种冷门配置,在 FrankenPHP 下都可能变成隐性故障点。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











