[php-src] Issue #18950: PHP 8+ @ suppressed errors cannot be distinguished anymore in many cases

From: Date: Thu, 26 Jun 2025 21:11:09 +0000
Subject: [php-src] Issue #18950: PHP 8+ @ suppressed errors cannot be distinguished anymore in many cases
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-250332@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/18950 Author: kkmuffme ### Description https://www.php.net/manual/en/migration80.incompatible.php >The @ operator will no longer silence fatal errors >([E_ERROR](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-error), >[E_CORE_ERROR](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-core-error), >[E_COMPILE_ERROR](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-compile-error), >[E_USER_ERROR](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-user-error), >[E_RECOVERABLE_ERROR](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-recoverable-error), >[E_PARSE](https://www.php.net/manual/en/errorfunc.constants.php#constant.e-parse)). Error handlers >that expect error_reporting to be 0 when @ is used, should be adjusted to use a mask check instead: While in PHP<8 this meant error_reporting is set to 0 when @ is used, in PHP 8+ you'd expect that it's set to 4437 when @ is used - which seems to be the case, except not if the error type is excluded already by the error_reporting level OR if it's included but does not contain all of the error types* This means, it's not possible anymore to distinguish @ suppressed and non-suppressed errors errors that would not report bc the error reporting level excludes them. The following code: ```php <?php function log_error( $type, $message, $file, $line ) { $error_reporting = error_reporting(); echo $error_reporting . ' - ' . ( $error_reporting & $type ) . PHP_EOL; } set_error_handler( 'log_error' ); trigger_error( 'A', E_USER_NOTICE ); @trigger_error( 'A', E_USER_NOTICE ); $constants = ['E_ERROR', 'E_USER_ERROR', 'E_USER_WARNING', 'E_USER_NOTICE', 'E_DEPRECATED', 'E_USER_DEPRECATED', 'E_RECOVERABLE_ERROR', 'E_ALL']; foreach ( $constants as $constant ) { echo $constant . ': ' . constant( $constant ) . PHP_EOL; error_reporting( constant( $constant ) ); trigger_error( 'A', E_USER_NOTICE ); @trigger_error( 'A', E_USER_NOTICE ); } ``` Resulted in this output with PHP 8.4: https://3v4l.org/Y4rlG#v8.4.8 ``` -1 - 1024 4437 - 0 E_ERROR: 1 1 - 0 1 - 0 E_USER_ERROR: 256 256 - 0 256 - 0 E_USER_WARNING: 512 512 - 0 0 - 0 E_USER_NOTICE: 1024 1024 - 1024 0 - 0 E_DEPRECATED: 8192 8192 - 0 0 - 0 E_USER_DEPRECATED: 16384 16384 - 0 0 - 0 E_RECOVERABLE_ERROR: 4096 4096 - 0 4096 - 0 E_ALL: 30719 30719 - 1024 4437 - 0 ``` Resulted in this output with PHP 7.4: https://3v4l.org/Y4rlG#v7.4.33 ``` -1 - 1024 0 - 0 E_ERROR: 1 1 - 0 0 - 0 E_USER_ERROR: 256 256 - 0 0 - 0 E_USER_WARNING: 512 512 - 0 0 - 0 E_USER_NOTICE: 1024 1024 - 1024 0 - 0 E_DEPRECATED: 8192 8192 - 0 0 - 0 E_USER_DEPRECATED: 16384 16384 - 0 0 - 0 E_RECOVERABLE_ERROR: 4096 4096 - 0 0 - 0 E_ALL: 32767 32767 - 1024 0 - 0 ``` But I expected this output instead: Not really sure what would make sense. e.g. ``` <?php function log_error( $type, $message, $file, $line ) { if ( $type === E_DEPRECATED ) { return true; } $error_reporting = error_reporting(); echo $error_reporting . ' - ' . ( $error_reporting & $type ) . PHP_EOL; return true; } set_error_handler('log_error'); //error_reporting( E_ALL ); error_reporting( E_ERROR ); trigger_error( 'A', E_USER_ERROR ); @trigger_error( 'A', E_USER_ERROR ); ``` in 7.4 https://3v4l.org/0fIc8#v7.4.33 ``` 1 - 0 0 - 0 ``` in 8.4 https://3v4l.org/0fIc8#v8.4.8 ``` 1 - 0 1 - 0 ``` *It's impossible to know whether it was suppressed or not: or e.g. https://3v4l.org/MmGIp#v8.4.8 ``` <?php function log_error( $type, $message, $file, $line ) { $error_reporting = error_reporting(); echo $error_reporting . ' - ' . ( $error_reporting & $type ) . PHP_EOL; } set_error_handler( 'log_error' ); error_reporting( ( E_ERROR | E_USER_NOTICE ) ); trigger_error( 'A', E_USER_NOTICE ); @trigger_error( 'A', E_USER_NOTICE ); ``` PHP 8.4 ``` 1025 - 1024 1 - 0 ``` 7.4 ``` 1025 - 1024 0 - 0 ``` ### PHP Version ```plain PHP 8.4 ``` ### Operating System _No response_

« previous php.bugs (#250332) next »