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

Uopz seems to kill composer autoload #166

Open
coopan opened this issue Sep 21, 2022 · 5 comments
Open

Uopz seems to kill composer autoload #166

coopan opened this issue Sep 21, 2022 · 5 comments
Labels

Comments

@coopan
Copy link

coopan commented Sep 21, 2022

PHP: 7.4.30
uopz: 6.1.1

Hi. I'm using this package as a dependency of PHP MockClock. Uopz is installed in a php docker container using the following:

# Build extensions
FROM bref/php-74-console:latest AS ext

# Setup php7.4 for build
RUN yum install -y amazon-linux-extras && amazon-linux-extras install php7.4

# Install packages
RUN yum install -y php-pear php-devel gcc make unzip zip

# Install mysql, zip, unzip from self-built
COPY config/serverless/layers/*.zip /tmp
RUN unzip /tmp/*.zip -d /tmp/mysql

# Build xdebug and uopz (for ClockMock)
RUN pecl channel-update pecl.php.net
RUN pecl install xdebug uopz-6.1.1
RUN cp /usr/lib64/php/modules/xdebug.so /tmp/xdebug.so
RUN cp /usr/lib64/php/modules/uopz.so /tmp/uopz.so

# Base image
FROM bref/php-74-fpm-dev:latest

# Copy things we installed to the final image
COPY --from=ext /tmp/xdebug.so /opt/bref/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so
COPY --from=ext /tmp/uopz.so /opt/bref/lib/php/extensions/no-debug-non-zts-20190902/uopz.so
COPY --from=ext /tmp/mysql /opt

# overwrite with our own php-fpm config (to allow concurrency)
COPY /php/php-fpm.conf /opt/bref/etc/php-fpm.conf

# Install things we need on final image
RUN yum install -y amazon-linux-extras file unzip zip

# Install gd
RUN amazon-linux-extras enable php7.4 && yum install -y php-gd
RUN cp /usr/lib64/php/modules/gd.so /opt/bref/lib/php/extensions/no-debug-non-zts-20190902/gd.so

# Run PHP-FPM as root
# opcache.validate_timestamps=1 : cancels the flag in the base configuration so that files are reloaded
CMD /opt/bin/php-fpm --nodaemonize --fpm-config /opt/bref/etc/php-fpm.conf -d opcache.validate_timestamps=1 --force-stderr --allow-to-run-as-root

This actually worked at one point, and I think it has something to do with composer installs. But on multiple instances of this docker setup, we are seeing the following error on ANY page load:

php              | NOTICE: PHP message: PHP Fatal error:  Uncaught Error: Call to undefined method ComposerAutoloaderInit51b2d8a3b9de3cdcc3490f52082af4ba::getLoader() in /var/task/vendor/autoload.php:7
php              | Stack trace:
php              | #0 /var/task/web/index.php(5): require_once()
php              | #1 {main}
php              |   thrown in /var/task/vendor/autoload.php on line 7

Even if we manually follow that trace inside the container itself, the exact class and method it is complaining about being undefined, exist just fine. Also, if I remove extension = uopz from the php.ini for the container and rebuild it, all is fine without any other interaction with code.

Any ideas?

@cmb69
Copy link
Collaborator

cmb69 commented Sep 26, 2022

Do you have configured uopz.exit=1? Also note that as of uopz 7.0.0, PHP 7 is no longer supported.

@coopan
Copy link
Author

coopan commented Sep 27, 2022

Thanks for the response. I didn't have uopz.exit=1 in my php.ini. I just tried that and it doesn't seem to have any impact. Same error.

I did wonder if this is a compatibility thing with xdebug, which the above dockerfile installs the latest 3.x version. I played around with this, installing down to 2.9.3. But unfortunately it presents the same error (with or without uopz.exit). Even unloading xdebug entirely doesn't resolve it.

Yes I'm aware support for PHP 7 drops at version 7. Preparing for a PHP 8 upgrade now is what led us to uopz in the first place (replacing timecop with ClockMock in our tests). The plan was simply upgrade uopz when we got to PHP 8 and have this dependcy sorted ahead of time.

@coopan
Copy link
Author

coopan commented Sep 27, 2022

Further info on this after playing with the docker setup over the last few days:

  1. Log error on every page load: PHP Fatal error: Uncaught Error: Call to undefined method ComposerAutoloaderInit51b2d8a3b9de3cdcc3490f52082af4ba::getLoader() in /var/task/vendor/autoload.php
  2. Results in a 500 error in logs. Impact is that local dev machines don’t work and branch doesn’t build since functional tests fail with their endpoints are throwing 500s.
  3. We have confirmed that the undefined method in that error definitely exists in the docker container the error is reported from.
  4. Attempts at resolving:
    1. Removing timecop extension ❌
    2. Different version of uopz. Tried 6.1.0, 6.1.1 and 6.1.2 ❌
    3. Different version of xdebug. Tried 2.9.3, 2.9.4, 2.9.8 and the current 3.x ❌
    4. Setting opcache.enable=0 in php.ini. This actually solves it. But it is not a solution. ✅
    5. Unloading xdebug from php.ini. This allows the first page load after rebuilding the docker container, but subsequent loads hit the same error (further suggesting opcache incompatibility) ❌
    6. Adding uopz.exit=1 in php.ini. ❌
  5. Other notes
    1. Found [a post](opcache do not update class constant after uopz_redefine #63) about “loading uopz before opcache per docs” but don’t see direction on how that should be done nor any doc that suggests this. I’m guessing this based on PHP module .ini files load order, but we don’t have those files. We load .so files in the main php.ini and opcache is already there without the need to do that.

@cmb69
Copy link
Collaborator

cmb69 commented Sep 28, 2022

  1. Found [a post](opcache do not update class constant after uopz_redefine #63) about “loading uopz before opcache per docs” but don’t see direction on how that should be done nor any doc that suggests this.

I think that requirement had actually been documented somewhere, but maybe this is no longer required for recent uopz versions. Anyway, it shouldn't harm to load the extension in that order.

I’m guessing this based on PHP module .ini files load order, but we don’t have those files. We load .so files in the main php.ini and opcache is already there without the need to do that.

The order in which the extensions are listed in a single php.ini matters. opcache.so must be loaded via some mechanism (some php.ini file, or maybe as option passed to the php executable), and you need to find out how it is loaded to be able to change the load order. The documentation at https://www.php.net/manual/en/configuration.php should help with that.

@cmb69
Copy link
Collaborator

cmb69 commented Aug 3, 2024

Is this still an issue with uopz 7.1.1? Note that at this point it wouldn't make sense to even attempt to fix uopz 6 (i.e. for support for PHP prior to 8.0.0).

@cmb69 cmb69 added the question label Aug 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants