PHPUnit 6.5.5 の Phar が PHP 7.0.10 で動かない件


wget https://phar.phpunit.de/phpunit-6.5.phar

docker run --rm php:7.0.10 php --version
# PHP 7.0.10 (cli) (built: Aug 31 2016 00:20:34) ( NTS )
# Copyright (c) 1997-2016 The PHP Group
# Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

docker run --rm -v $PWD:/app -w /app php:7.0.10 php phpunit-6.5.phar --version
# Fatal error: Cannot use PHPUnit\Framework\MockObject\Stub as Stub because the name is already in use in phar:///app/phpunit-6.5.phar/phpunit-mock-objects/Builder/InvocationMocker.php on line 16                                                                                       

名前空間 PHPUnit\Framework\MockObject\BuilderStub クラスを定義しているにも関わらず、同じ名前空間の InvocationMocker.phpuse PHPUnit\Framework\MockObject\Stub as Stub しているため、名前が競合することが原因。

なお、順番が逆なら動くので、Composer とかで PHPUnit を入れている場合は動くかもしれない(未確認)。Phar 版の場合はスタブコードで require されているので確実に動かない。

これは PHP のバグらしく、PHP 7.0.13 で修正されている。

なので 7.0.13 以降だと発生しない。

docker run --rm -v $PWD:/app -w /app php:7.0.13 php phpunit-6.5.phar --version
# PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

ワークアラウンドとして、CLI で OPcache を有効にすれば動作する。

docker run --rm -v $PWD:/app -w /app php:7.0.10 \
  php -d zend_extension=opcache.so -d opcache.enable_cli=1 phpunit-6.5.phar --version
# PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

あるいは PHPUnit 6.4.4 なら発生しない。

wget https://phar.phpunit.de/phpunit-6.4.4.phar

docker run --rm -v $PWD:/app -w /app php:7.0.10 php phpunit-6.4.4.phar --version
# PHPUnit 6.4.4 by Sebastian Bergmann and contributors.