Edit report at https://bugs.php.net/bug.php?id=61747&edit=1
ID: 61747 User updated by: chealer at gmail dot com Reported by: chealer at gmail dot com Summary: User-defined error handler run despite at sign (@) error control operator Status: Not a bug Type: Bug Package: *General Issues PHP Version: 5.4.0 Block user comment: N Private report: N New Comment: I'm sorry. This was fixed in http://svn.php.net/viewvc/phpdoc/en/trunk/language/operators.xml?r1=322134&r2=323370 We now have: When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @. Note that this second sentence contradicts the first in some [edge] cases. At least, the second sentence should immediately follow the first, rather than having its own paragraph. Previous Comments: ------------------------------------------------------------------------ [2012-04-16 20:39:54] ras...@php.net The documentation is quite clear I think. In the first link you provided it says: If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @. I see no reason to change anything here. The current approach gives you all the control you need. If you have a custom error handler you can decide whether you want to ignore silenced calls or not. Any change to this would also be a major BC break. ------------------------------------------------------------------------ [2012-04-16 17:57:52] chealer at gmail dot com Description: ------------ The at sign operator allows to "ignore" error messages, as explained in http://ca3.php.net/manual/en/language.operators.errorcontrol.php When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. However, as reported in #61091, user-defined error handlers registered with set_error_handler() are nevertheless run when @ is used, which often causes such messages to show, as in the below example, where a custom error handler is used to customize the display of error messages. As http://ca3.php.net/manual/en/language.operators.errorcontrol.php#98895 and http://ca3.php.net/manual/en/language.operators.errorcontrol.php#85042 show, this problem is not new. This behavior appears to be by design, and might be wanted in some cases. Therefore, please either: Stop calling user-defined error handlers when suppressing errors. This needs serious consideration for backwards-compatibility. Allow specifying whether user-defined error handlers should be called when suppressing errors. Make the documentation reflect the current state of things. Alternatively, if the documentation of the @ operator isn't amended because custom error handlers are considered a corner case, then the set_error_handler() documentation should warn developers tempted to use custom error handlers that they are non-standard, not recommended/supported, and try to explain the pitfalls. In short, tell developers they should only use a custom error handler if they know what they're doing. However, this alternative should be avoided since set_error_handler() is already used in several applications whose developers didn't receive the warning. Test script: --------------- <?php function myErrorHandler($errno, $errstr) { switch ($errno) { case E_USER_ERROR: echo "<b>My ERROR</b> [$errno] $errstr<br />\n"; echo " Fatal error on line $errline in file $errfile"; echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n"; echo "Aborting...<br />\n"; exit(1); break; case E_USER_WARNING: echo "<b>My WARNING</b> [$errno] $errstr<br />\n"; break; case E_USER_NOTICE: echo "<b>My NOTICE</b> [$errno] $errstr<br />\n"; break; default: echo "Unknown error type: [$errno] $errstr<br />\n"; break; } } // function to test the error handling function scale_by_log($vect, $scale) { if (!is_numeric($scale) || $scale <= 0) { trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale", E_USER_ERROR); } if (!is_array($vect)) { trigger_error("Incorrect input vector, array of values expected", E_USER_WARNING); return null; } $temp = array(); foreach($vect as $pos => $value) { if (!is_numeric($value)) { trigger_error("Value at position $pos is not a number, using 0 (zero)", E_USER_NOTICE); $value = 0; } $temp[$pos] = log($scale) * $value; } return $temp; } $a = array(2, 3, "foo", 5.5, 43.3, 21.11); /* Value at position $pos is not a number, using 0 (zero) */ scale_by_log($a, M_PI); @scale_by_log($a, M_PI); set_error_handler("myErrorHandler"); @scale_by_log($a, M_PI); ?> Expected result: ---------------- Notice: Value at position 2 is not a number, using 0 (zero) in /var/www/atoperator.php on line 42 Call Stack: 0.0005 339192 1. {main}() /var/www/atoperator.php:0 0.0005 339836 2. scale_by_log(array (0 => 2, 1 => 3, 2 => 'foo', 3 => 5.5, 4 => 43.3, 5 => 21.11), 3.1415926535898) /var/www/atoperator.php:55 0.0006 340648 3. trigger_error('Value at position 2 is not a number, using 0 (zero)', 1024) /var/www/atoperator.php:42 Actual result: -------------- Notice: Value at position 2 is not a number, using 0 (zero) in /var/www/atoperator.php on line 42 Call Stack: 0.0005 339192 1. {main}() /var/www/atoperator.php:0 0.0005 339836 2. scale_by_log(array (0 => 2, 1 => 3, 2 => 'foo', 3 => 5.5, 4 => 43.3, 5 => 21.11), 3.1415926535898) /var/www/atoperator.php:55 0.0006 340648 3. trigger_error('Value at position 2 is not a number, using 0 (zero)', 1024) /var/www/atoperator.php:42 <b>My NOTICE</b> [1024] Value at position 2 is not a number, using 0 (zero)<br /> ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=61747&edit=1