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

CodeIgniter3应用升级PHP8.2后PHP-FPM报Bad file descriptor错误求助

解决PHP 8.2 + CodeIgniter 3 下的PHP-FPM "Bad file descriptor" 错误

针对你遇到的ERROR: unable to read what child 15029 said into stderr: Bad file descriptor (9)错误,结合你的环境(PHP8.2.x + Debian12 + CodeIgniter3),以下是针对性的排查和解决步骤:

1. 优先解决CodeIgniter3与PHP8.2的兼容性问题

CodeIgniter3原生版本对PHP8.2的支持不完善,很多底层函数和类型处理在PHP8.2下会触发隐性错误,进而导致FPM子进程异常退出,最终引发这个描述符错误:

  • 给CI3打PHP8.2兼容补丁:社区有不少针对CI3的PHP8.x兼容补丁,重点修复create_function废弃、类型声明严格模式冲突、each()函数移除等问题;
  • 检查自定义代码和第三方库:排查应用中直接操作文件、Socket、日志的代码,确保进程退出前正确关闭所有打开的文件描述符;老版本的数据库驱动、缓存库等第三方依赖可能在PHP8.2下存在资源泄漏;
  • 开启详细错误日志:
    • 在php.ini中设置error_reporting = E_ALL、log_errors = On;
    • 在CI3的application/config/config.php中设置log_threshold = 4,捕获所有级别的应用错误——很多时候FPM的描述符错误只是表象,背后是代码层面的报错导致子进程崩溃。

2. 调整PHP-FPM的输出捕获配置

这个错误本质是FPM主进程读取子进程stderr时遇到无效描述符,可通过调整FPM配置优化输出处理:

  • 在PHP-FPM pool配置文件(通常为/etc/php/8.2/fpm/pool.d/www.conf)中:
    • 确保catch_workers_output = yes,开启子进程输出捕获;
    • 设置decorate_workers_output = no,避免输出格式干扰主进程读取;
    • 明确指定error_log = /var/log/php8.2-fpm.log,并确保www-data用户对该日志路径有写入权限;
    • 添加php_admin_flag[log_errors] = on和php_admin_value[error_log] = /var/log/php8.2-fpm-www.log,单独捕获当前pool的错误日志,避免和主日志混淆;
  • 修改后执行systemctl restart php8.2-fpm生效。

3. 排查Debian12系统层面的资源限制

Debian12默认的资源限制可能不匹配PHP8.2的需求,导致子进程无法正常创建或释放描述符:

  • 调整文件描述符限制:
    • 编辑/etc/security/limits.conf,添加:
      www-data soft nofile 65535
      www-data hard nofile 65535
      
    • 执行ulimit -n 65535临时生效,重启系统后永久生效;
  • 检查systemd对FPM的限制:
    • 编辑/etc/systemd/system/php8.2-fpm.service(或/lib/systemd/system/php8.2-fpm.service),添加或修改:
      LimitNOFILE=65535
      LimitNPROC=65535
      
    • 执行systemctl daemon-reload && systemctl restart php8.2-fpm生效。

4. 调试FPM子进程的退出原因

通过工具跟踪子进程的行为,定位具体触发错误的场景:

  • 开启FPM慢日志:在pool配置中添加:
    slowlog = /var/log/php8.2-fpm-slow.log
    request_slowlog_timeout = 5s
    
    查看慢日志中是否有长时间运行的请求导致子进程异常;
  • 使用strace跟踪FPM进程:
    strace -p $(pidof php-fpm8.2) -e trace=file,read,write,exit
    
    当错误出现时,观察输出中描述符9的操作细节,以及子进程退出的信号(比如SIGSEGV、SIGKILL);
  • 检查系统日志:查看/var/log/syslog和/var/log/dmesg,排查是否有OOM killer杀掉FPM子进程的记录(关键词php-fpm、Out of memory)。

5. 临时禁用PHP8.2的新特性

PHP8.2的部分新特性可能和CI3的老代码冲突,可尝试临时禁用排查:

  • 在php.ini中设置zend.max_execution_timer = 0,关闭新的执行定时器特性;
  • 关闭OPcache:设置opcache.enable = 0,重启FPM后观察错误是否消失,排除OPcache缓存导致的子进程崩溃。

内容的提问来源于stack exchange,提问作者N.J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:53:13