GitHub Actions多版本PHP测试必须通过matrix策略显式声明php-version并分层拦截,setup-php的php-version不支持环境变量插值,需硬编码或走matrix,且每个版本须独立运行PHPCompatibility、PHPStan、PHPUnit等四层门禁,失败即阻断。

GitHub Actions 多版本 PHP 测试流水线不是“多个版本跑一遍”就完事,而是必须让每个版本独立验证、分层拦截、失败即阻断——否则你看到的“全绿”只是假象。
php-version 字段不支持环境变量插值,必须硬编码或走 matrix
很多人想用 env.PHP_VERSION 动态传给 shivammathur/setup-php@v2 的 php-version,结果 workflow 直接报错 Invalid workflow file。这不是写法问题,是 GitHub Actions 语法限制:with: 下所有字段都不接受上下文表达式(${{ }})。
- ✅ 正确做法:用
strategy.matrix.php-version显式列出目标版本,如['7.4', '8.1', '8.3', '8.5'] - ✅ 单版本调试时,直接写死
php-version: '8.4',再用env:同步其他环节(如composer config platform.php ${{ env.PHP_VERSION }}) - ❌ 不要尝试
php-version: ${{ env.PHP_VERSION }}或php-version: ${{ secrets.PHP_VERSION }},必然失败
setup-php 必须显式启用扩展,否则 PHPUnit 会报 Class not found
Ubuntu runner 自带的 PHP 环境极简,ext-pdo、ext-mbstring、ext-xml 这些基础扩展默认不加载。你本地能跑通的测试,在 CI 里可能第一行就崩在 new PDO() 或 json_encode() 上。
- 必须在
setup-php的with.extensions中明确列出全部依赖扩展,例如:mbstring, xml, curl, pdo, pdo_mysql, json - 若项目用到
ext-intl或ext-gd,也得加进去,漏一个就可能让composer install跳过关键包 - 禁用
xdebug(加coverage: none),它和 PHP 8.2+ 的 JIT 编译器冲突,会导致php -v直接 segfault
PHPCompatibility 扫描必须指定 --runtime-set testVersion,否则默认只查 5.6
vendor/bin/phpcs --standard=PHPCompatibility 单独运行,默认只检查 PHP 5.6 兼容性——哪怕你当前用的是 PHP 8.5,它也不会报 str_contains() 在 8.0+ 才可用这类问题。
立即学习“PHP免费学习笔记(深入)”;
- 必须显式加参数:
--runtime-set testVersion 7.4-8.5(换成你实际支持的区间) - 推荐写进
composer.json的scripts里,例如:"compat-check": "phpcs --standard=PHPCompatibility --runtime-set testVersion 7.4-8.5 src/" - CI 中调用
composer compat-check,比手敲命令更可靠,也方便统一控制路径和扩展名
PHPUnit 必须每个版本独立跑,不能靠“最高版本兼容就代表全兼容”
PHP 8.1 的枚举、8.2 的只读类、8.4 的 #[\Override]、8.5 的 password_hash() 新参数……这些特性不是向下兼容的。你在 8.5 下跑通的测试,很可能在 8.0 下因 match 语法报错、或因动态属性赋值被拒绝而失败。
- 每个
matrix.php-version必须触发完整流程:安装依赖 → 运行phpcs→ 运行phpstan→ 运行phpunit - 不要跳过低版本的测试步骤(比如
if: matrix.php-version == '7.4'就只跑兼容扫描),因为行为差异只能靠真实运行暴露 - 特别注意
phpunit.xml中的bootstrap路径和ini-settings,某些版本需要额外opcache.enable_cli=1才能通过 autoload
最易被忽略的一点:matrix 并行测试下,不同 PHP 版本的 composer install 可能因 platform.config.php 没对齐而装出不同依赖树——务必在 workflow 开头用 composer config platform.php ${{ matrix.php-version }} 强制锁定平台版本。



















