Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The class_alias in bootstrap.php causes warnings when using preloading #47

Closed
hussainweb opened this issue Jul 13, 2020 · 7 comments
Closed

Comments

@hussainweb
Copy link

I am using a generated preloading script which looks something like this:

$loader = require_once '/app/web/autoload.php';
// more lines to load PSR-4 directories (irrelevant to this issue)

$files = [
    '/app/vendor/autoload.php',
    '/app/load.environment.php',
    '/app/vendor/composer/autoload_static.php',
    // more files to be preloaded
];

foreach ($files as $file) {
    try {
        if (!(is_file($file) && is_readable($file))) {
            throw new \Exception("{$file} does not exist or is unreadable.");
        }
        require_once $file;
    } catch (\Throwable $e) {
        // ...
        throw $e;
    }
}

This script is set to opcache.preload setting. The script works and I see that the preload is making a difference, but there is a warning on all pages.


Warning: Cannot declare class DrupalCodeGenerator\Twig\TwigEnvironment, because the name is already in use in /app/vendor/chi-teck/drupal-code-generator/src/bootstrap.php on line 44

Warning: Cannot declare class DrupalCodeGenerator\TwigEnvironment, because the name is already in use in /app/vendor/chi-teck/drupal-code-generator/src/bootstrap.php on line 47

After debugging, I realized this is because bootstrap.php is loaded by composer (it's part of composer.json's autoload.files option). As the warnings suggest, this is due to the class_alias line.

After a lot of debugging and research, I conclude that the problem is that the preloading works somewhat differently for class_alias. In other words, this could be a PHP bug and I do some hints for this in php/php-src#3538 and symfony/symfony#29105.

My theory is that while preloading correctly handles all the regular classes and functions, it cannot handle class_alias properly. Since class_alias runs both while preloading (as we are requiring the autoloader) and during the execution, it seems that the internal PHP entry for the class name persists during the runtime causing the warning.

The fix in my case was to wrap the class_alias call inside an if block with class_exists condition. I don't see any warnings after that. I'm going to create a PR against 1.x branch for that shortly.

Footnote: This is tangentially related to #46 but I don't know if this change would help static analyzers.

@Chi-teck
Copy link
Owner

What is your PHP version?
PHP prior to version 7.4.2 had some issues with preloading.

@hussainweb
Copy link
Author

@Chi-teck, it's PHP 7.4.8.

@hussainweb
Copy link
Author

hussainweb commented Jul 13, 2020

Also, do you remember what kind of issues were there before PHP 7.4.2? I could use that for the documentation for the module I am working on. Thanks! :)

@Chi-teck
Copy link
Owner

I am not quite sure. I've just found this quote from @nikic

I should probably clarify that 7.4.1 will not contain all the preloading fixes. Some of them will only make 7.4.2

The PHP release notes contain some useful references. Try to search "preloading" on that page.
https://www.php.net/ChangeLog-7.php#PHP_7_4

@hussainweb
Copy link
Author

Thanks! I'll include all that in the documentation. Please let me know if I can help here in another way.

Chi-teck added a commit that referenced this issue Jul 15, 2020
Fixes #47: Alias classes only if they haven't been aliased before.
@Chi-teck
Copy link
Owner

Fixed in #48. Thank you.

@hussainweb
Copy link
Author

Thank you for merging this and also creating a release. It makes my documentation much easier. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants