You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OPcache bypasses the user-defined error handler for deprecations #17422
The OPcache bypasses the user-defined error handler for deprecations for the first request with a cold cache. This happens regardless of opcache.record-warnings which only has an impact on all following requests. Enabling opcache.record-warnings will yield the expected behavior for every request after the first one which populated the cache.
This does not happen when OPcache is disabled, it will behave properly for every request.
This can be reproduced on a web server whenever opcache_reset() reset is invoked but for simplicity this was also verified to be triggered via CLI (thanks to @TimWolla for this suggestion):
$> php -dopcache.enable_cli=1 --repeat 2 test.php
Executing for the first time...
PHP Deprecated: implicitly_nullable_parameter(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in /opt/homebrew/var/www/test/opcache-deprecations/dependency.php on line 2
Deprecated: implicitly_nullable_parameter(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in /opt/homebrew/var/www/test/opcache-deprecations/dependency.php on line 2
Called
Finished execution, repeating...
Called
$> php --version
PHP 8.4.2 (cli) (built: Dec 17 2024 15:31:31) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.2, Copyright (c) Zend Technologies
with Zend OPcache v8.4.2, Copyright (c), by Zend Technologies
(Note: There is a bonus bug hiding here, the deprecation message is printed twice. However, the first message starts with PHP Deprecated: (…) but the second message only reads Deprecated: (…).)
The script was also invoked manually via CLI without OPcache to verify that the behavior is identical to FPM:
$> php test.php
array(4) {
[0]=>
int(8192)
[1]=>
string(141) "implicitly_nullable_parameter(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead"
*snip*
PHP Version
PHP 8.4.2
Operating System
macOS 15.1.1
Reacted by Sascha Greuel, Xopez, Christopher Walz, Jens Radtke, Tomáš Maxmilián Janíček, Toshiyuki Fujita, Szczepan Szczepaniak, Liviu Cristian Mirea-Ghiban, Tarmo Leppänen, Saša Stamenković and 10 more
(Note: There is a bonus bug hiding here, the deprecation message is printed twice. However, the first message starts with PHP Deprecated: (…) but the second message only reads Deprecated: (…).)
I stand corrected, this is caused by log_errors being enabled, thanks to @TimWolla for pointing this out:
$> php -dopcache.enable_cli=1 -dlog_errors=0 --repeat 2 test.php
Executing for the first time...
Deprecated: implicitly_nullable_parameter(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in /opt/homebrew/var/www/test/opcache-deprecations/dependency.php on line 2
Called
Finished execution, repeating...
Called
Reacted by Jens Radtke, Pim Broekhof, Szczepan Szczepaniak, mikehartogtalent, Liviu Cristian Mirea-Ghiban, WeDevelop Development, Sergei Predvoditelev, FranzBruckner, Tomáš Maxmilián Janíček, kaliberx and 2 more
Confirming seeing this issue, that specific deprecation ignoring our error handlers messes up our json outputs and blocks us from upgrading to 8.4. Fixing all deprecations isn't an option, as we can do so in our own code but not in the packages that we use.
Reacted by Liviu Cristian Mirea-Ghiban, Sergei Predvoditelev, Jens Radtke, WeDevelop Development, FranzBruckner, Pim Broekhof, Venca, asrar, kaliberx, Saša Stamenković and 6 more
This has been fixed in version 8.5. Unfortunately this can not be fixed in earlier versions due to complexity and breaking changes.
A possible workaround for 8.4, when a user-defined error handler is in place, is to remove E_DEPRECATED from error_reporting: symfony/symfony@9a7f7a3. In effect, this will prevent displaying/logging E_DEPRECATED errors entirely (including during compilation), but will still call the user-defined error handlers (except during compilation): https://gist.github.com/arnaud-lb/47bc1e93f01e6740e2dbbc2e44b27f3d.
Activity
TimWolla commentedon Jan 10, 2025
OPcache explicitly clears the user error handler in:
php-src/ext/opcache/ZendAccelerator.c
Line 1806 in d8d1cb4
before compiling the file. This is done since the first version of the open source OPcache, so it's not clear to me, why it does this.
tomasjanicek commentedon Jan 16, 2025
I have same problem on php version 8.4.1
kkmuffme commentedon Jan 17, 2025
Works correctly for me (Rocky Linux)
jmglsn commentedon Jan 20, 2025
Bug is still present on PHP 8.4.3.
dtdesign commentedon Jan 29, 2025
I stand corrected, this is caused by
log_errorsbeing enabled, thanks to @TimWolla for pointing this out:DylanGD commentedon Feb 25, 2025
The bug is still present on PHP 8.4.4
kbalashov1 commentedon Mar 13, 2025
Confirming seeing this issue, that specific deprecation ignoring our error handlers messes up our json outputs and blocks us from upgrading to 8.4. Fixing all deprecations isn't an option, as we can do so in our own code but not in the packages that we use.
umpirsky commentedon Apr 9, 2025
The bug is still present on PHP 8.4.5.
aszenz commentedon Apr 9, 2025
I can confirm this issue is present on our symfony app
lewischadwick commentedon Apr 16, 2025
Confirmed this still happens on PHP 8.4.6 too.
opcache: Do not disable userland error handlers in `opcache_compile_f…
vencakrecl commentedon May 14, 2025
Is it still the same on PHP 8.4.7?
boewamwinter commentedon May 21, 2025
Yes it is for me.
bug #60779 Silence E_DEPRECATED and E_USER_DEPRECATED (nicolas-grekas)
bug #60779 Silence E_DEPRECATED and E_USER_DEPRECATED (nicolas-grekas)
Hanashi commentedon Jun 24, 2025
Bug is still present in PHP 8.4.8
Fix error handling inconsistency with opcache
arnaud-lb commentedon Jul 27, 2025
This has been fixed in version 8.5. Unfortunately this can not be fixed in earlier versions due to complexity and breaking changes.
A possible workaround for 8.4, when a user-defined error handler is in place, is to remove
E_DEPRECATEDfromerror_reporting: symfony/symfony@9a7f7a3. In effect, this will prevent displaying/loggingE_DEPRECATEDerrors entirely (including during compilation), but will still call the user-defined error handlers (except during compilation): https://gist.github.com/arnaud-lb/47bc1e93f01e6740e2dbbc2e44b27f3d.php84 needs nullable arguments to be explicitly nullable. You'd think…