Well... This is my case: I'm developing a framework and I'm current developing the error handling feature. I want handle error handling errors too! Well... explaining better: If I have an error, fatal or not, is thrown an exception (in case of non fatal errors) and faked Exception for fatal errors. The exceptions are handled by "loggers", which can treat the error echo it on console (browser) or store it on a file. The problem is when occurs a second FATAL error inside loggers. To catch it I'm using PHP buffer (ob_start()). Inside this function should never occurs an error, anyone.... In the other words... this is last level of the error tracing. I could just echo the error, but I want register them using PHP error log system (disabled if not reach last level). This is possible using error_log function. In PHP documentation for error_log function:
"Returns TRUE on success or FALSE on failure."
Well... this what I need. But I'm afraid because I don't know if this function could generate fatal error (internal implementation) or just return TRUE/FALSE. I tested using mail option (1) in localhost SMTP and this failed (as expected!), generating a warning message. Then buffer crashes displaying blank page on browser (this is what I don't want happen). This problem could be solved checking smtp connectivity with fsockopen and attribuiting the return value to a class variable. Inside buffer function this variable value is verified. If is TRUE, error_log with email option is called. But in the case of error_log with options 0 (php file log) and 3 (other files)?
This goes the relevant part of my logging class:
public function error_buffer($buffer) {
$error = error_get_last ();
if ($error && ($error ['type'] & E_FATAL && $this->_errhe)) {
$this->error_handler_error ( $error ['type'], $error ['message'], $error ['file'], $error ['line'] );
if (ENV === 'production') {
return 'error 500';
}
return ob_get_contents ();
}
return $buffer;
}
public function error_handler_error($errno, $errmsg, $errfile, $errline) {
var_dump ( $errfile );
/* GENERATES WARNING MESSAGE... AND BLANK PAGE!
* Here is possible to do: if($this->_email) { error_log() }...
*/
@error_log ( $errmsg, 1, '[email protected]' );
// error_log($errmsg, 0);
}
The @ doesn't stop an error from hapenning, it only stops it from being displayed. So if mail() fails, then error_log to email (options 1) will also fail - with an error.
Therefore, what is probably happening is that error_log() call causes an error that calls your error handling function, that calls error_log() that causes an error that calls your error handling function, that calls error_log() that causes an error that calls your error handling function, that calls error_log() that causes an error that.... you get the gist.
If that's the case, the solutions I can quickly think of are:
1 - to include a static variable in error_buffer to say "I'm currently handling an error, don't handle any more (or simply display the message on screen - but honor the ini setting "display_errors").
2 - to turn off your error handling when in your error function to default PHP functions handle it.
Why not make a call to "error_log ( $errmsg, 1, '[email protected]' );" outside the error function (with our without the @) and see if you error handler is being called?