PHP-FPM 中 disable_classes 为何显示单值却禁用了两个类?
数据小陈
结论
这两种现象可能同时出现:phpinfo() 显示的是配置项当前记录的字符串值,而禁用类的设置可能分别来自 php.ini 和 PHP-FPM pool 配置。因此,页面上即使只显示 ReflectionFunction,ReflectionClass 也可能仍处于禁用状态。
问题中的配置如下:
; php.ini
disable_classes = ReflectionClass
; PHP-FPM pool 配置
php_admin_value[disable_classes] = 'ReflectionFunction'
PHP-FPM 配置文档说明,pool 中的 disable_classes 新值会追加到 php.ini 中已有的值,而不是直接覆盖。disable_classes 接受以逗号分隔的类名列表。这样,两个类都可能被禁用,但 phpinfo() 配置行显示的只是最后设置的字符串值,不会列出合并后的禁用类列表。PHP-FPM 配置文档 PHP 核心配置文档
如何核对
- 检查实际处理网页请求的 PHP-FPM 实例及其 pool 配置,确认对应的
php.ini路径和配置加载顺序。CLI 使用的 PHP 配置不一定与 FPM 相同。 - 在同一个 FPM 请求中查看
phpinfo(),核对disable_classes的 Local Value、Master Value,以及已加载的配置文件信息。 - 分别尝试实例化这两个类,确认实际运行结果是否与配置一致。
disable_classes针对内部类,并阻止它们被实例化,不应作为完整的安全隔离措施。 - 修改配置后重载或重启 PHP-FPM,再次检查,以免把旧 worker 的状态当作新配置的结果。
php_admin_value 用于 pool 级别的管理配置,脚本不能通过 ini_set() 覆盖它。若要启用某个类,需要从所有生效的配置中移除它,并确认 PHP-FPM 已重新加载配置。
版本注意
题目未提供 PHP 版本。PHP 官方手册注明,disable_classes 已从 PHP 8.5.0 移除;上述说明适用于仍支持该指令的版本。请先核对 FPM 实际运行的版本,再判断这项配置是否适用。PHP 核心配置文档
备注:内容仅供参考。
