PHP探针适配多版本的关键在于环境路由而非代码兼容,需通过Nginx location分流或CLI绝对路径明确指定PHP执行入口,再依赖phpversion()和phpinfo()原生输出。
PHP探针本身是纯 PHP 脚本,不依赖特定 SAPI 或扩展,但「适配多 PHP 版本」的关键不在探针代码,而在部署方式和运行上下文——你不能让一个 phpinfo() 页面同时显示 PHP 7.4 和 PHP 8.2 的结果,必须明确控制由哪个 php 可执行文件来解析它。
常见误区:把同一份 probe.php 放进 Nginx + PHP-FPM 多版本共存环境(如 php74-fpm / php82-fpm),却只配置了一个 upstream,导致浏览器访问时始终走默认池。实际生效的不是文件位置,而是 FPM 的 socket 或端口绑定关系。
fastcgi_pass 指向哪个 php-fpm.sock 或 127.0.0.1:9001,就决定用哪个 PHP 版本执行 probe.php
php probe.php 时,php 命令是否为软链接、是否在 $PATH 中靠前,直接影响版本选择$_SERVER['SERVER_SOFTWARE'] 或尝试调用 shell_exec('php -v'),若权限受限或禁用函数,会返回空或报错,造成「版本识别失败」假象无需改探针代码,靠 Nginx 配置分流:每个 PHP 版本对应一个独立 URL 路径,并绑定专属 FPM 进程池。
location /probe74/ {
alias /var/www/probe/;
index probe.php;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index probe.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
location /probe82/ {
alias /var/www/probe/;
index probe.php;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index probe.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
probe.php 文件,但执行时分别被 PHP 7.4 和 8.2 解析alias 后路径末尾带斜杠,SCRIPT_FILENAME 用 $request_filename 确保真实路径正确,避免 404root + rewrite,容易因路径拼接出错导致探针无法加载自身开发或运维排查时常需在终端直跑探

/usr/bin/php7.4 probe.php > result74.html;/usr/bin/php8.2 probe.php > result82.html
php 命令指向:which php 和 php -v,再用 update-alternatives --config php(Debian/Ubuntu)或 ln -sf 切换软链接php.ini 完全独立:探针中 ini_get('display_errors') 在 CLI 下默认 off,FPM 下可能 on,结果不一致属正常部分老探针会用 phpversion() + PHP_OS + extension_loaded() 拼凑环境信息,看似全面,但在容器或精简发行版中易漏判。
shell_exec('cat /etc/os-release') 类命令——Docker 容器常无该文件,或权限拒绝memory_limit、max_execution_time 等配置项在不同 SAPI 下默认值不同,探针显示的是当前运行模式下的实际值,不是全局配置文件值get_cfg_var() 读取未启用的配置(如 opcache 启用前查 opcache.enable),会返回 false,而非 null,容易误判为「关闭」多版本适配的本质是环境路由问题,不是代码兼容问题。最稳妥的做法永远是:明确指定执行入口(Nginx location / CLI 绝对路径),然后信任 phpversion() 和 phpinfo() 的原生输出——它们不会说谎,但你得让对的 PHP 进程去跑它。