Error_get_last () and custom error handler

odbc_errormsg does not report odbc_execute error messages as intended. He just warns. So I was forced to write a hack to parse the error message through error_get_last .

I use set_error_handler and error_get_last returns NULL if I, too:

  • disable my error handler

  • or return it to FALSE .

I would suggest that this is due to the PHP builtin error handler, which takes care of storing the error data somewhere so that it can be found later.

Is there a way to emulate this behavior in my custom error handler, so error_get_last() can be used normally?

Please note: I already know several ways to get error information at any time. My question is how to make error_get_last useful.


Update: I think I better place the code.

PHP has error_get_last() , which allows you to do this:

 @fopen('xxx'); var_dump( error_get_last() ); 

... and get the following:

 array(4) { ["type"]=> int(2) ["message"]=> string(46) "fopen() expects at least 2 parameters, 1 given" ["file"]=> string(69) "C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php" ["line"]=> int(3) } 

This breaks if you replace the built-in error handler:

 function custom_error_handler($errno, $errstr, $errfile, $errline){ $ignore = ($errno & error_reporting()) == 0; if(!$ignore){ echo "[Error happened: $errstr]\n"; } return TRUE; } set_error_handler('custom_error_handler'); @fopen('xxx'); var_dump( error_get_last() ); // NULL 

If you save both error handlers ...

 function custom_error_handler($errno, $errstr, $errfile, $errline){ $ignore = ($errno & error_reporting()) == 0; if(!$ignore){ echo "[Error happened: $errstr]\n"; } return FALSE; } set_error_handler('custom_error_handler'); error_reporting(E_ALL); echo $foo; 

... you get side effects:

 [Error happened: Undefined variable: foo] Notice: Undefined variable: foo in C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php on line 15 Call Stack: 0.0004 329720 1. {main}() C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php:0 

... instead of just:

 [Error happened: Undefined variable: foo] 

I want my custom error handler to interact correctly with error_get_last . I want error_get_last work fine.

+7
source share
2 answers

That's right, this is a weird decision, but I think it will suit your goals.

After a little game, I found that it was:

 function my_error_handler ($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array()) { // Handle the error here @trigger_error($errstr); return TRUE; } // Just to make sure PHP is not outputting anything error_reporting(-1); ini_set('display_errors',1); set_error_handler('my_error_handler'); // An E_USR error... trigger_error('Some error'); var_dump(error_get_last()); // ...and a native one $key = count(); var_dump(error_get_last()); 

Results in this:

 array(4) { ["type"]=> int(1024) ["message"]=> string(10) "Some error" ["file"]=> string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.php" ["line"]=> int(7) } array(4) { ["type"]=> int(1024) ["message"]=> string(45) "count() expects at least 1 parameter, 0 given" ["file"]=> string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.php" ["line"]=> int(7) } 

Calling @trigger_error() from your error handler and not returning FALSE results in returning error_get_last() for something other than NULL , but since the error is suppressed with @ , PHP does not output anything. It seems that in the interest of avoiding infinite recursion, calling trigger_error() from the registered function of the error handler does not call the error handler - this works in our interests here.

Obviously, the error code has been changed, but if you need to convert it to the corresponding E_USR_* code, but I suspect that you really want it, this is the string value that this method will allow you to get. You, unfortunately, also lost the line number and file information - although you could get it back by doing something that included stack tracing inside the error handler, or at least including it in the line of the passed arguments.

This is a terrible, terrible, terrible hack, but since there is no officially sanctioned way to do this, hacking is essentially what you are asking for.

+5
source

You can change your own error handler to return false only when the error is ignored (using the @ operator).

 function custom_error_handler($errno, $errstr, $errfile, $errline){ $ignore = ($errno & error_reporting()) == 0; if ($ignore) { return FALSE; } echo "[Error happened: $errstr]\n"; return TRUE; } 
0
source

All Articles