应使用 version_compare() 判断版本后动态加载逻辑,而非尝试 mock PHP_VERSION 或 PHP_VERSION_ID;因常量不可重定义、只读整数赋值无效,mock 实质是条件分支+静态分析;推荐按版本拆分文件并条件包含,对 polyfill 场景优先用 function_exists()。
直接用
判断版本再加载对应逻辑,比 mock PHP 版本常量更可靠;PHP 本身不提供运行时“切换版本”的能力,所谓“Mock”本质是条件分支 + 静态分析辅助验证。
为什么不能真 mock PHP_VERSION 或 PHP_VERSION_ID
强行覆盖
常量会触发 fatal error(常量不可重定义);
是只读整数,赋值无效且无意义。试图用
会报
,后续
仍读取真实值。mock 的目标不是骗过 PHP 解析器,而是让测试能覆盖不同版本路径的执行逻辑。
用条件加载 + 文件隔离模拟多版本行为
把版本敏感代码拆到独立文件中,按需包含,避免解析失败中断整个测试流程:
PHP 8.0+ 功能(如
、联合类型)写在
,入口处用
PHP 7.4 专属逻辑(如箭头函数)放
,但注意:该文件不能被 PHP require
低版本降级实现统一放在
,例如用
替代
,用
替代
类型声明
测试时如何验证不同版本路径都走通
靠静态分析工具提前扫出语法风险,而不是等测试运行时报错:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
用
+
规则集,指定
检查是否含
或
—— 这些在 7.4 下合法,但在 7.3 下会直接 parse error
对同一份代码,分别跑
在 Docker 启动的 PHP 7.2、7.4、8.1 容器里,检测语法是否通过(
不执行,只解析)
单元测试中不 mock 版本号,而是用
控制测试分支,CI 中启动多个 job,每个 job 设置不同环境变量并运行对应测试集
别忽略扩展版本和函数可用性的交叉判断
主版本号只是起点,真正卡住的是扩展行为差异。例如
在 PHP 7.4 和 8.0 中
返回值类型不同;
扩展的
在旧版中不支持某些选项。这些无法靠
捕获:
检查扩展存在性必须先
,再用
获取其版本
对函数可用性,优先用
而非
,因为 polyfill 可能已注入该函数
某些函数(如
)PHP 8.3 才引入,但部分 polyfill 库会提前提供,此时
比版本判断更贴近实际运行态
version_compare()PHP_VERSIONPHP_VERSION_IDdefine('PHP_VERSION', '7.4.0')Notice: Constant PHP_VERSION already definedversion_compare()matchfeatures/v80.phpif (version_compare(PHP_VERSION, '8.0.0', '>=')) { require 'features/v80.php'; }features/v74.phpfeatures/fallback.phpif-elseifmatchis_string() || is_int()string|intphpcsPHPCompatibility--runtime-set testVersion 7.4matchfn()php -lphp -lgetenv('TEST_PHP_VERSION')mbstringmb_ord()curlcurl_setopt_array()version_compare(PHP_VERSION)extension_loaded('mbstring')phpversion('mbstring')function_exists('str_contains')version_compare(PHP_VERSION, '8.0.0', '>=')json_validate()function_exists()