I develop in Vagrant VM with Ubuntu 12.04 and php 5.5.7. and faced problem of incorrect error reporting handling in this case: @-sign works incorrectly.
When using custom error handlers and globally turned on error reporting, @-calls (such as @unlink('...')
) should trigger custom handler but calling error_reporting()
from it should return 0 in this case:
http://ca3.php.net/manual/en/language.operators.errorcontrol.php
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 @.
But in fact it returns -1!
Googling have not resulted in anything.
Have anyone any idea, how to make it work correctly? And what can cause this?
The question is not about using or not using of @-sign. Even if I don't use it, vendors of third-party packages use it. And don't tell me that this packages are bad because of it, you will be wrong. In some situations, when using @ wisely, it can fix issues caused by bad design of old native php functions that produce warnings in places where they should not. But this is a hollywar and doesn't matter in question context.
The question is about making it work correctly in given environment and localization of issue source
Problem was found, see accepted answer
Well, I've found the problem... Xdebug is installed, and the problem is there.
Xdebug docs say:
xdebug.scream
Type: boolean, Default value: 0, Introduced in Xdebug >= 2.1
If this setting is 1, then Xdebug will disable the @ (shut-up) operator so that notices, warnings and errors are no longer hidden.
But by some reason, after installing it via apt-get install -y php5-xdebug
it sets scream
to 1
in /etc/php5/mods-available/xdebug.ini
From php.net, WARNING message
Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why.
Is equialent:
error_reporting(0);
unlink('...'); // and error reporting always return 0
error_reporting(E_ALL);
If you want to process the unlink, you must to check that file exists before unlink it
$file = 'path/to/file.txt';
if(file_exists($file))
{
unlink($file);
}
P.S. Don't use "@" - it is very bad code style and bad solution by performance. See the test with @ and without it
If you're wondering what the performance impact of using the @ operator is, consider this example. Here, the second script (using the @ operator) takes 1.75x as long to execute...almost double the time of the first script.
So while yes, there is some overhead, per iteration, we see that the @ operator added only .005 ms per call. Not reason enough, imho, to avoid using the @ operator.
Without "@"
for ($i = 0; $i < 1000000; $i++) { $undefined; }
real 0m7.617s
user 0m6.788s
sys 0m0.792s
And with "@"
for ($i = 0; $i < 1000000; $i++) { @$undefined; }
real 0m13.333s
user 0m12.437s
sys 0m0.836s