erorr_reporting() and @ operator

php.internals

Benjamin Morel

5 years ago
Hi internals, Since PHP 8.0, `error_reporting()` started returning a non-zero value when the @ silence operator is used. Demo: https://3v4l.org/CovYv Is this intentional? This breaks scripts that converted all errors to exceptions, except those where the silence operator was used: set_error_handler(function ($severity, $message, $file, $line) { if (error_reporting() === 0) { return; } throw new ErrorException($message, 0, $severity, $file, $line); }); Thank you, Benjamin

Nikita Popov

5 years ago
On Wed, Dec 2, 2020 at 2:56 PM Benjamin Morel <benjamin.morel@gmail.com> wrote:
> Hi internals, > > Since PHP 8.0, `error_reporting()` started returning a non-zero value when > the @ silence operator is used. > > Demo: https://3v4l.org/CovYv > > Is this intentional? This breaks scripts that converted all errors to > exceptions, except those where the silence operator was used: > > set_error_handler(function ($severity, $message, $file, $line) { > if (error_reporting() === 0) { > return; > } > > throw new ErrorException($message, 0, $severity, $file, $line); > }); > > Thank you, > Benjamin >
Search for "error_reporting()" on https://www.php.net/manual/en/migration80.incompatible.php, it discusses exactly this code ;) Regards, Nikita

Benjamin Morel

5 years ago
Thanks for the pointer, Nikita. I think the updated example (using `error_reporting() & $errno`) fails to mimic exactly what `error_reporting() === 0` did, though. Say your php.ini mutes E_WARNING, for example: error_reporting = E_ALL & ~E_WARNING Checking for `error_reporting() === 0` allowed to only ignore @-suppressed statements, but still throw an exception on E_WARNING, ignoring the error_reporting set in php.ini. OTOH, checking for `error_reporting() & $errno` still allows to ignore @-suppressed statements, but **also ignores E_WARNING configured in php.ini**, which is not always what userland code wants. I'm not sure how userland code can now replicate the old behaviour, i.e. specifically detect the @ operator? — Benjamin

Nikita Popov

5 years ago
On Wed, Dec 2, 2020 at 3:14 PM Benjamin Morel <benjamin.morel@gmail.com> wrote:
> Thanks for the pointer, Nikita. > > I think the updated example (using `error_reporting() & $errno`) fails to > mimic exactly what `error_reporting() === 0` did, though. > > Say your php.ini mutes E_WARNING, for example: > > error_reporting = E_ALL & ~E_WARNING > > Checking for `error_reporting() === 0` allowed to only ignore @-suppressed > statements, but still throw an exception on E_WARNING, ignoring the > error_reporting set in php.ini. > > OTOH, checking for `error_reporting() & $errno` still allows to > ignore @-suppressed statements, but **also ignores E_WARNING configured in > php.ini**, which is not always what userland code wants. > > I'm not sure how userland code can now replicate the old behaviour, i.e. > specifically detect the @ operator? >
First off: Please don't do this. Error_reporting should be respected independently of how it was set. Now, if you do want to approximately distinguish @, you can do it the same way you did before: Check for the value it sets. Previously that was 0 (which you also couldn't distinguish from error_reporting=0 set in php.ini). Now it will be E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE, or whatever that evaluates to. Regards, Nikita