必须分别验证CLI与Web环境的php.ini路径及扩展加载状态:运行php --ini查CLI配置,访问phpinfo()页面查Web实际加载的ini;php -m仅反映命令行扩展,Web需确认对应SAPI的php.ini中extension=已启用且extension_dir路径正确。

PHP环境“看起来能跑”不等于“真正可用”,很多问题出在CLI和Web SAPI加载了不同php.ini、扩展只在命令行生效、或关键配置被运行时覆盖。验证必须分层击破,不能只靠php -v或一个phpinfo()页面。
怎么确认当前PHP加载的是哪个php.ini
同一台机器上常存在多个php.ini:CLI用一个,Apache用一个,php-fpm又可能用第三个。改错文件等于白改。
- 命令行下运行
php --ini,看Loaded Configuration File路径——这是CLI实际读的 - Web环境下访问
phpinfo()页面,搜索Loaded Configuration File——这才是Apache/Nginx+PHP实际加载的 - 如果
Loaded Configuration File显示(none),说明PHP没读到任何ini,所有配置都是默认值 -
Scan for additional .ini files目录下的文件也会被加载,但顺序靠后,可能覆盖主ini里的设置
为什么php -m显示mysqli,但网页里报Class 'mysqli' not found
因为php -m查的是CLI SAPI的扩展列表,而Web请求走的是另一个SAPI(如apache2handler或fpm-fcgi),两者扩展启用状态完全独立。
- 在
phpinfo()页面顶部找Server API字段,确认当前是哪种SAPI - 检查该SAPI对应的
php.ini里是否真有extension=mysqli(Linux/macOS是.so,Windows是.dll) - 注意扩展路径是否正确:
extension_dir必须指向含mysqli.so的目录,否则即使写了extension=mysqli也加载失败 - FPM模式下改完
php.ini必须sudo systemctl restart php-fpm,不是重启Nginx
如何检测php.ini里关键项是否被运行时修改
有些框架或部署脚本会用ini_set()或putenv()动态覆盖配置,导致phpinfo()里看到的值≠初始值,排查时容易误判。
立即学习“PHP免费学习笔记(深入)”;
- 用
sebastian/environment的getCurrentSettings()可对比初始值与当前值:$runtime->getCurrentSettings(['memory_limit', 'upload_max_filesize']) - 手动比对:在脚本开头调用
ini_get('memory_limit'),再在结尾调一次,看是否变化 -
display_errors被设为Off但错误仍不显示?检查是否有error_reporting(0)或ini_set('error_reporting', 0)在代码里强行关掉 - 某些Docker镜像或PaaS平台会禁用
ini_set(),此时ini_get()返回的永远是php.ini原始值
临时目录不可写会导致哪些典型故障
很多开发者只测phpinfo()和echo,却忽略sys_get_temp_dir()是否真实可写——这会让Composer、Laravel缓存、PHPUnit临时文件全跪。
- 执行
is_writable(sys_get_temp_dir()),返回false就直接停手,别往下试 - 常见原因:SELinux限制(Linux)、权限组不匹配(如Web服务用
www-data用户,但/tmp属root)、磁盘满、挂载为noexec或nosuid - 不要硬改
/tmp权限,应通过sys_temp_dir配置项指定项目专用临时目录,并确保Web进程对该目录有读写权限 - Laravel项目若报
Failed to clear cache,90%先查这个



















