Skip to content

[PHP 8.4] Deprecation notice inconsistencies with opcache enabled #16897

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

Closed
lebris opened this issue Nov 22, 2024 · 18 comments
Closed

[PHP 8.4] Deprecation notice inconsistencies with opcache enabled #16897

lebris opened this issue Nov 22, 2024 · 18 comments

Comments

@lebris
Copy link

lebris commented Nov 22, 2024

Description

I am observing inconsistent behavior with deprecation notices using php 8.4.1 when opcache is enabled.
Some deprecation notice disapeared after having been displayed few times.

Code to reproduce :

<?php

declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors', true);

// php 8.3 deprecation : triggered every time
$a = 'blabla';
$a--;

// php 8.4 deprecation : triggered once
function implicitNullable(string $foo = null) {}

Here's the output when sending few requests (with apache2 in my case)

for i in {0..5}; do curl http://localhost ;done
<br />
<b>Deprecated</b>:  implicitNullable(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in <b>/var/www/html/index.php</b> on line <b>14</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />

Observed Behavior

  • The "implicit nullable" deprecation appears only once (or twice in my app) and stops appearing.
  • The "decrement on non-numeric string" deprecation appears on every request as expected.

Expected Behavior

  • Both deprecation notices should appear consistently on every request.

Note : When disabling opcache, both deprecation notices are displayed consistently on every request.

Is this a bug or I am missing something ?

In this example I'm using php 8.4.1 from the official docker image php:8.4-apache and the default php configuration.

I made a repo here where you can find everything to reproduce easely : https://github.com./lebris/php8.4-deprecation-opcache

PHP Version

PHP 8.4.1

Operating System

No response

@Girgias
Copy link
Member

Girgias commented Nov 22, 2024

The "implicit nullable" deprecation is a compile time deprecation, which only happens once when Opcache is used, as that is what opcache does.

Not sure if this can be fixed @iluuu1994 ?

@iluuu1994
Copy link
Member

iluuu1994 commented Nov 22, 2024

Opcache records and replays warnings (see zend_begin_record_errors()). I don't know why it doesn't work here.

@cmb69
Copy link
Member

cmb69 commented Nov 22, 2024

opcache.record_warnings is Off by default.

@lebris, does it work if you set opcache.record_warnings=1 in your php.ini?

@lebris
Copy link
Author

lebris commented Nov 22, 2024

With opcache.record_warnings=1 it works as expected. Thanks

for i in {0..10}; do curl -k http://localhost/ ; done
<br />
<b>Deprecated</b>:  implicitNullable(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in <b>/var/www/html/index.php</b> on line <b>14</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  implicitNullable(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in <b>/var/www/html/index.php</b> on line <b>14</b><br />
<br />
<b>Deprecated</b>:  Decrement on non-numeric string has no effect and is deprecated in <b>/var/www/html/index.php</b> on line <b>10</b><br />
<br />
<b>Deprecated</b>:  implicitNullable(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in <b>/var/www/html/index.php</b> on line <b>14</b><br />
[...]

Is this behavior (requiring opcache.record_warnings=1) intentional since PHP 8.4 ?
Should it be enabled by default (at least in dev envs) to ensure consistent reporting of deprecation warnings ?

@cmb69
Copy link
Member

cmb69 commented Nov 22, 2024

To my knowledge, opcache.record_warnings is available as of PHP 8.4.0, and defaulted to Off since it was introduced. You may only notice this now, since both deprecations are new (as of PHP 8.4.0).

I'm fine with leaving this Off by default, but won't mind enabling it by default. If you want to change the default, please write to the internals mailing list.

@iluuu1994
Copy link
Member

Ah ok, I didn't know this setting was off by default. It makes sense, little reason to throw deprecations that always occur on every request, that just hurts performance. I think this can be closed then.

Should it be enabled by default (at least in dev envs) to ensure consistent reporting of deprecation warnings ?

There's really no point, unless you just want to flood your logs more.

@iluuu1994 iluuu1994 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 22, 2024
@iluuu1994
Copy link
Member

To my knowledge, opcache.record_warnings is available as of PHP 8.4.0

Just the warning is new, not this option.

@cmb69
Copy link
Member

cmb69 commented Nov 22, 2024

Oops, meant PHP 8.0.0.

@vencakrecl
Copy link

vencakrecl commented Jan 4, 2025

I have a similar issue with nginx + php-pfm. The deprecation notice kills the FPM process. The opcache ignores the error_reporting setting.

error_reporting=E_ALL & ~E_DEPRECATED
opcache.enable=1
Screenshot 2025-01-04 at 22 33 25

@cmb69
Copy link
Member

cmb69 commented Jan 4, 2025

Are you sure that is OPcache, and not some error handler which promotes the deprecation notice to an exception which is not caught?

@vencakrecl
Copy link

@cmb69 When I use opcache.enable=0, the request is ok.

@cmb69
Copy link
Member

cmb69 commented Jan 7, 2025

@vencakrecl, while your issue might be related to this ticket, I suggest to file a new issue – try to provide an SSCCE, though.

@tomasjanicek
Copy link

tomasjanicek commented Jan 16, 2025

I have same problem when opcache is enabled deprecations are showing in first load request and ignore error reporting settings. (problem started after upgrade from php 8.3 to 8.4.1)

@chewbackhaus
Copy link

We are experiencing the same issue in PHP Version 8.4.3. We see the deprecation warnings the first time the page is loaded and then subsequent loads don't show anything.

The change to set opcache.record_warnings=1 did not work, so we had to disable the opcache which made the errors show up on each page load.

@iluuu1994
Copy link
Member

I still can't reproduce this.

<?php

function implicitNullable(string $foo = null) {}

php -d opcache.enable=1 -S 127.0.0.1:8080 test.php

First page load shows the deprecation, subsequent do not.

php -d opcache.enable=1 -d opcache.record_warnings=1 -S 127.0.0.1:8080 test.php

Warning appears on every page load.

@chewbackhaus How did you enable the INI? Note that this ini setting is a INI_SYSTEM, meaning you can only enable it through php.ini or httpd.conf (not at runtime).

@chewbackhaus
Copy link

I enabled it through the php.ini. It could be something with our specific configuration though.

@iluuu1994
Copy link
Member

Maybe you have a error handler installed? In that case, it would actually be related to #17422.

a.php

<?php
set_error_handler(function () {});
require __DIR__ . '/b.php';

b.php

<?php
function implicitNullable(string $foo = null) {}

This produces the behavior described in this issue. However, it's not that the error isn't emitted, but rather that the error handler is called for one but not the other. Could this be what you're observing?

@DylanGD
Copy link

DylanGD commented Feb 25, 2025

related to #17422, still waiting for a fix.

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

No branches or pull requests

8 participants