PHPUnit 9在PHP 8.0+环境运行报each()未定义如何解决
问题现象
使用PHPUnit做单元测试,在PHP 8.0及以上版本环境运行时抛出如下致命错误:
Fatal error: Uncaught Error: Call to undefined function each() in C:\xampp\php\pear\PHPUnit\Util\Getopt.php:80 Stack trace: #0 C:\xampp\php\pear\PHPUnit\TextUI\Command.php(242): PHPUnit_Util_Getopt::getopt(Array, 'd:c:hv', Array) #1 C:\xampp\php\pear\PHPUnit\TextUI\Command.php(138): PHPUnit_TextUI_Command->handleArguments(Array) #2 C:\xampp\php\pear\PHPUnit\TextUI\Command.php(129): PHPUnit_TextUI_Command->run(Array, true) #3 C:\xampp\php\phpunit(46): PHPUnit_TextUI_Command::main() #4 {main} thrown in C:\xampp\php\pear\PHPUnit\Util\Getopt.php on line 80
根因说明
报错和PHPUnit 9版本本身无关,你当前实际运行的是XAMPP默认通过PEAR安装的PHPUnit 5.x及更早的老旧版本,不是你预期安装的PHPUnit 9。
PHP从7.2版本开始标记内置函数each()为废弃状态,8.0版本直接移除了该函数,旧版PEAR渠道发布的PHPUnit依赖大量PHP8已移除的废弃语法/函数,完全不兼容PHP8.0+环境,才会触发这个报错。本质是系统环境变量优先级问题,旧版全局PHPUnit覆盖了新版PHPUnit的调用路径。
排查步骤
- 命令行执行
phpunit --version,查看输出的版本号与执行路径,会发现返回的是5.x及更早版本,执行路径指向C:\xampp\php\pear\目录,和报错路径一致。 - 检查系统环境变量的Path配置顺序,确认XAMPP的pear相关路径优先级高于你自己安装新版PHPUnit的路径,导致命令行默认调用旧版本。
解决方案
- 第一步先清理旧版本冲突:执行
pear uninstall phpunit/PHPUnit,彻底卸载XAMPP自带的老旧PEAR版PHPUnit,避免后续版本冲突。 - 项目本地安装(推荐):在项目根目录执行
composer require --dev phpunit/phpunit ^9.6,该版本完全兼容PHP8.0-8.2环境。后续运行测试时调用项目内的执行文件./vendor/bin/phpunit即可,不要直接调用全局命令。 - 全局安装新版PHPUnit(可选):如果需要全局调用phpunit命令,执行
composer global require phpunit/phpunit ^9.6安装全局兼容版本,之后将Composer全局bin目录(Windows系统默认路径是C:\Users\你的用户名\AppData\Roaming\Composer\vendor\bin)调整到系统环境变量Path的最顶部,优先级高于XAMPP相关路径,保证命令行默认调用新版。
注意:不要尝试手动修改旧版PHPUnit源码替换
each()函数来临时兼容,旧版本和PHP8的不兼容点多达数十处,修改完当前报错后还会持续触发其他函数移除、语法不兼容的报错,没有实际使用价值。
内容的提问来源于stack exchange,提问作者Mehuol Dhanji
相关产品推荐
相关产品推荐

