phpinfo 找不到配置文件

服务器上跑着一套 PHP 项目,配置浏览器打开 phpinfo() 页面,文件Loaded Configuration File 那一行赫然写着 (none)。配置这事我遇到过不下十次,文件每次都是配置不同的原因。最离谱的文件一回,是配置运维把 php.ini 文件放到了 /etc/php.ini,但编译 PHP 时 --with-config-file-path 指向了 /usr/local/php/lib。文件两个路径八竿子打不着,配置PHP 启动时自然找不到配置文件。文件

很多人第一反应是配置去查 php.ini 是不是没放对地方。这个思路没错,文件但不够细。配置PHP 找配置文件是文件有顺序的,编译时指定的配置路径排在最前面,然后是环境变量 PHPRC 指定的目录,再往后才是当前工作目录。如果你用的是 Docker 或者宝塔面板,情况会更绕——容器里的 PHP 可能压根没打包 php.ini,只有一个 php.ini-production 躺在 /usr/local/etc/php/ 下面,没人去改它的名字。

有个客户半夜打电话说网站报错,提示 upload_max_filesize 太小。我让他看 phpinfo(),结果连配置文件都没加载。他用的是一台 Windows Server,PHP 解压在 D:\php,但 php.ini 被重命名成了 php.ini.txt——Windows 默认隐藏已知扩展名,他以为改好了,其实文件还是文本格式。这种细节,光看 phpinfo() 的 (none) 根本猜不到。

Linux 下更常见的是权限问题。配置文件路径对了,文件名也对,但 PHP-FPM 的运行用户没有读取权限。比如 /etc/php/8.1/fpm/php.ini 的属主是 root:root,权限 600,而 FPM 池配置里 user = www-data。PHP 进程以 www-data 身份去读这个文件,直接被拒。这时候 phpinfo() 不会告诉你“权限不够”,它只会安静地显示 (none)。你得去看 FPM 的日志,或者用 strace 跟一下 open() 系统调用。

还有一种情况是 CLI 和 FPM 用了不同的配置。你在命令行跑 php -i | grep php.ini,显示加载了 /etc/php.ini,但浏览器里 phpinfo() 还是 (none)。因为 CLI 的 php.ini 搜索路径和 FPM 的不一样。CLI 可能读的是 /etc/php/8.1/cli/php.ini,而 FPM 读的是 /etc/php/8.1/fpm/php.ini。两个目录下只有一个放了文件,另一个是空的。这种分裂在 Debian/Ubuntu 系上特别常见,因为包管理器的目录结构本来就分 cli 和 fpm。

我自己的习惯是,拿到一台新机器先跑 php --ini,看 CLI 加载了哪些文件。然后写个 info.php 丢到 web 目录,浏览器访问,对比 Loaded Configuration File 和 Scan this dir for additional .ini files。如果 Loaded Configuration File 是 (none),但 Scan this dir 有路径,那说明扫描目录里的 .ini 文件还是生效的——PHP 会加载 conf.d 下的所有 .ini。这时候你改 php.ini 没用,得去 conf.d 里加文件。

最省事的排查方法:在 phpinfo() 页面搜索 Configuration File (php.ini) Path。这个值就是编译时写死的默认路径。如果这个路径下没有 php.ini,PHP 就会继续往后找。把 php.ini-production 复制过去,重命名成 php.ini,重启 FPM 或 Apache,问题基本就解决了。但别忘了检查 PHPIniDir 这个 Apache 指令——如果你在 httpd.conf 里写了 PHPIniDir "/etc/php",那 Apache 模块版的 PHP 就只认这个目录,别的路径全忽略。

说到底,phpinfo() 显示 (none) 不是 PHP 的 bug,是配置链上某一环断了。编译参数、环境变量、文件权限、SAPI 差异、包管理器目录结构,任何一个环节出问题都会导致这个结果。别急着改代码,先把 php --ini 和 phpinfo() 两个输出并排放在一起看,差异点就是线索。