php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81678 Class definition file will sometimes not load with opcache.enable_cli=1
Submitted: 2021-11-30 20:39 UTC Modified: -
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: eric at ericstern dot com Assigned:
Status: Open Package: opcache
PHP Version: 8.1.0 OS: macOS 11.4 (intel)
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2021-11-30 20:39 UTC] eric at ericstern dot com
Description:
------------
After updating to PHP 8.1.0, I'm observing PHPStan failing to discover a class that's a) unchanged since updating and b) always worked fine. This appears to be specific to running `opcache.enable_cli=1`, as the class loads just fine with enable_cli disabled.

While I was initially inclined to file the issue with PHPStan (or even Composer), I've observed that this only happens on my macOS install of 8.1.0, and not inside Docker (Alpine 3.15). That leads me to believe it's an issue with opcache or PHP itself.

Stranger still, if I shoehorn a `class_exists` to trigger autoloading of the class into Composer's autoloader script (using their native loader), the class in question loads fine. Doing the same by manually `require`ing the file also works. However, if I do so inside a conditional (see test script), it does NOT work. Same situation for all of include/include_once/require/require_once.

One additional file load fails if I use those manual hacks (in this case, a trait and not an abstract class), but the same manual effects apply to that trait and fix the loading in the same way.

JIT is disabled.

I don't have issues loading this class in e.g. PHPUnit, nor during php-fpm execution. So honestly I have no idea where the actual issue comes from. Happy to provide any additional details that would help.

Test script:
---------------
This is the file that will not process:

https://github.com/Firehed/inputobjects/blob/3.3.1/src/Structure.php

The file is loaded normally through composer, and used (and therefore loaded) only via `extends`.

Autoloader snippet:

<?php
require_once __DIR__ . '/composer/autoload_real.php';
$l = ComposerAutoloaderInit3f9a650a956cc97446cf6d0adafdfd0d::getLoader();
// class_exists(Firehed\InputObjects\Structure::class); // <-- this works
spl_autoload_register(function ($class) {
    // require_once __DIR__ . '/firehed/inputobjects/src/Structure.php'; // <-- this works
    if ($class === 'Firehed\\InputObjects\\Structure') {
        $file = __DIR__ . '/firehed/inputobjects/src/Structure.php';
        var_dump(class_exists($class)); // bool(false)
        $result = require $file; // <-- this does NOT work
        var_dump($result); // int(1), even if I add a return statement to the file itself
        var_dump(class_exists($class)); // bool(false)
    }
}, prepend: true);

return $l;

Expected result:
----------------
File is included normally, loads fine, etc.

Actual result:
--------------
Requiring the file has no effect in some situations, despite require's return value indicating success.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-30 20:55 UTC] eric at ericstern dot com
Might be the same as https://bugs.php.net/bug.php?id=81542, didn't see that during my initial search.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Thu Jan 27 18:03:33 2022 UTC