Description
Description
https://www.php.net/manual/en/migration80.incompatible.php
The @ operator will no longer silence fatal errors (E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, 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
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
PHP 8.4
Operating System
No response