根本原因是cli与web服务器(如php-fpm)加载不同的php.ini配置、扩展和运行环境;需分别用php --ini和phpinfo()确认实际配置路径,并重点比对display_errors、error_log、extension、open_basedir等项。

命令行能跑通,网页一打开就报错或白屏,根本原因不是代码写错了,而是PHP在两种场景下用的不是同一套配置。命令行(CLI)和Web服务器(如Apache/Nginx+PHP-FPM)各自加载独立的php.ini、扩展、环境变量甚至二进制路径——它们本质是两个不同的PHP“实例”。
查清实际加载的配置文件
很多人以为php --ini看到的就是网页用的配置,其实不是。CLI和FPM用的是不同php.ini:
- 命令行执行:
php --ini显示CLI SAPI的配置路径 - 网页执行:新建一个
info.php,内容为<?php phpinfo(); ?>,通过浏览器访问,搜索"Loaded Configuration File"那一行——这才是Web服务真正读的ini - 两者路径经常不一致,比如CLI用
/etc/php/7.4/cli/php.ini,而FPM用/etc/php/7.4/fpm/php.ini
对比关键配置项是否开启
即使版本相同,以下几项配置差异足以让功能彻底失效:
- display_errors:CLI默认开,FPM常被设为Off → 导致网页静默失败,只留500
-
error_log:CLI日志可能输出到终端,FPM日志通常写入
/var/log/php-fpm/www-error.log或/var/log/apache2/error.log,不查就等于闭眼排障 -
extension_dir与extension:CLI启用的
mbstring,FPM ini里可能注释掉了;尤其注意opcache.so在FPM中是否启用,它会影响类自动加载行为 - open_basedir:FPM常限制可访问目录,而CLI无此限制 → 报"failed to open stream"却本地完全正常
确认扩展是否真实加载
仅看php -m不够,因为它是CLI的模块列表。网页环境必须单独验证:
- 在
phpinfo()页面搜索gd、pdo_mysql、redis等关键词,确认状态为"enabled" - 若某扩展在phpinfo里没出现,检查对应ini中是否漏了
extension=xxx.so,或.so文件路径错误(比如编译时路径硬编码) - FPM子进程可能因SELinux或权限问题无法加载扩展,此时错误日志里会出现
dlopen() failed提示
检查运行用户与权限上下文
CLI通常以当前登录用户身份运行,而Web服务以www-data、nginx或apache用户运行:
- 用
ps aux | grep php-fpm确认主进程用户,再检查缓存目录、上传目录是否对该用户可写(is_writable()可测) - 文件系统大小写敏感性:Windows本地不区分
Classname.php和classname.php,Linux线上严格区分 → require路径大小写错,CLI能过,网页直接报"no such file" - OPcache缓存未刷新:改完代码但FPM的
opcache.validate_timestamps=0,导致仍执行旧字节码 → 看似“代码没生效”,实为缓存陷阱
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











