php - poner - error_get_last() y controlador de error personalizado
poner mensaje de error en php (2)
Bien, esta es una solución extraña, pero creo que se adaptará a tus propósitos.
Después de jugar un poco, he descubierto que esto:
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());
Resultados en esto:
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)
}
Llamar a @trigger_error()
desde el controlador de errores y no devolver FALSE
, hace que error_get_last()
devuelva algo que no sea NULL
, pero como el error se suprime con @
, PHP no genera nada. Parece que a fin de evitar una recursión infinita, al llamar a trigger_error()
desde dentro de la función del controlador de errores registrado no se llama al controlador de errores, lo cual funciona a nuestro favor aquí.
Obviamente, el código de error ha sido modificado, pero puede convertirlo al código E_USR_*
si lo necesita, pero sospecho que lo que realmente quiere es el valor de la cadena, que este método le permitirá obtener. Desgraciadamente, también ha perdido el número de línea y la información del archivo, aunque es posible recuperarlo haciendo algo relacionado con un seguimiento de la pila dentro del controlador de errores o, como mínimo, incluyéndolo en la cadena de los argumentos aprobados.
Este es un truco horrible, horrible y horrible, pero como no hay una forma oficialmente aprobada de hacerlo, un pirateo es esencialmente lo que estás pidiendo.
odbc_errormsg
no informa los mensajes de error de odbc_execute
como se supone que debe hacerlo. Simplemente lanza una advertencia. Así que me he visto obligado a escribir un truco para analizar el mensaje de error a través de error_get_last
.
Estoy usando set_error_handler
y error_get_last
devuelve NULL
menos que yo:
deshabilitar mi controlador de errores,
o hacer que vuelva
FALSE
.
Supongo que esto se debe al controlador de error incorporado de PHP que se encarga de almacenar los detalles del error en algún lugar para que puedan ser recuperados más tarde.
¿Hay alguna forma de emular ese comportamiento en mi controlador de error personalizado para que error_get_last()
se pueda usar normalmente?
Tenga en cuenta que ya sé varias formas de recuperar la información de error en cualquier momento. Mi pregunta es cómo hacer que error_get_last
utilizable.
Actualización: creo que será mejor que publique un código.
PHP tiene error_get_last()
, que permite hacer esto:
@fopen(''xxx'');
var_dump( error_get_last() );
... y consigue esto:
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)
}
Esto se rompe si reemplaza el controlador de error incorporado:
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
Si mantiene ambos controladores de errores ...
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;
... obtienes efectos secundarios:
[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
... en lugar de simplemente
[Error happened: Undefined variable: foo]
Quiero que mi controlador de error personalizado se error_get_last
correctamente con error_get_last
. Quiero que error_get_last
funcione bien.
Puede cambiar su manejador de error personalizado para que devuelva falso, justo cuando se ignora el error (se usa @operador).
function custom_error_handler($errno, $errstr, $errfile, $errline){
$ignore = ($errno & error_reporting()) == 0;
if ($ignore) {
return FALSE;
}
echo "[Error happened: $errstr]/n";
return TRUE;
}