Skip to content

Commit ef043f8

Browse files
SanderMullerclaude
andcommitted
Explain the OPcache guard of the autoload trap e2e steps
Print a message when OPcache is not loaded, give the second step the same comment as the first, and say why the opcache_invalidate() loop after the trap cannot replace the one before it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent db3fa23 commit ef043f8

2 files changed

Lines changed: 7 additions & 3 deletions

File tree

‎.github/workflows/e2e-tests.yml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,14 @@ jobs:
259259
composer install
260260
# The crash needs OPcache: forked workers switch it off, the --debug main process and spawned
261261
# workers (pcntl_fork disabled, as on Windows) keep it on.
262-
php -r 'exit(extension_loaded("Zend OPcache") ? 0 : 1);'
262+
php -r 'if (!extension_loaded("Zend OPcache")) { fwrite(STDERR, "OPcache is not loaded, so this step cannot reproduce the crash.\n"); exit(1); }'
263263
../../bin/phpstan analyze --debug
264264
php -d disable_functions=pcntl_fork ../../bin/phpstan analyze
265265
- script: |
266266
cd e2e/bootstrap-autoloader-wrong-file
267-
php -r 'exit(extension_loaded("Zend OPcache") ? 0 : 1);'
267+
# The crash needs OPcache: forked workers switch it off, the --debug main process and spawned
268+
# workers (pcntl_fork disabled, as on Windows) keep it on.
269+
php -r 'if (!extension_loaded("Zend OPcache")) { fwrite(STDERR, "OPcache is not loaded, so this step cannot reproduce the crash.\n"); exit(1); }'
268270
../../bin/phpstan analyze --debug
269271
php -d disable_functions=pcntl_fork ../../bin/phpstan analyze
270272
- script: |

‎src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ static function () use ($className): ?array {
400400
* or a file a bootstrap autoloader included without declaring the class. With OPcache active, the
401401
* trapped include of that file runs the script OPcache compiled from the real file, not the empty
402402
* script FileReadTrapStreamWrapper serves, and dies with "Cannot redeclare". Invalidating the
403-
* entries of the included files makes that include go through the trap.
403+
* entries of the included files makes that include go through the trap. The opcache_invalidate()
404+
* loop after the trap cannot do this, because the include has already run by then. That loop removes
405+
* the empty script the trap left in OPcache.
404406
*
405407
* Forked workers switch OPcache off (see ForkedProcess), so they skip this.
406408
*/

0 commit comments

Comments
 (0)