My question is:
PHP has a great feature that allows you to convert errors that can occur in an application to Exceptions
. This can be done through the class ErrorException
Example:
set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$a = $b;
} catch(\Exception $e){
echo $e->getMessage(); // Undefined variable: b
}
This "catch error" works perfectly for errors like E_NOTICE
, E_WARNING
and etc ... However, when a Parse Error ( E_PARSE
) occurs, set_error_handler
is not able to capture it.
I was able to (more or less) capture this E_PARSE
through the register_register_shutdown_function
(it performs a function when php at the end of the script, even if execution is interrupted by E_PARSE
) in combination with the error_get_last
.
set_error_handler
. ob_start
combined with
a ob_end_clean
within the "catcher" of the error? Beforehand I already say:
To say that there is no way to do this is a lie, because Laravel 4
can perfectly turn E_PARSE
into exception too!
Update
Attheuser'srequest@gmsantos,IampostingthetransformationcodefromE_PARSE
toErrorException
,whichIthinkistheclosestIwant.
ThisiswhatIwasabletodousingregister_shutdown_function
(itwasveryfast,soitdoesnothaveanyobject-oriented:)):
<?phpob_start();echo'Olámundo';//Poressafunção,otry/catchconsegue"pegar" a exceção
set_error_handler(function($errno, $errstr, $errfile, $errline){
// Se o cara não colocar arroba, o erro é mostrado :)
if (error_reporting() !== 0) {
ob_clean(); // limpa o buffer e não imprime "Ólá mundo"
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
});
// aqui não dá pra usar try/catch :(
register_shutdown_function(function(){
// O register_shutdown_function só pode capturar E_PARSERs provenientes de include, e não no mesmo script
if ($err = error_get_last()) {
ob_clean(); // limpa o buffer e não imprime "Ólá mundo"
throw new ErrorException($err['message'], 0, $err['type'], $err['file'], $err['line']);
/*
Uncaught exception 'ErrorException' with message 'syntax error, unexpected '.''
in C:\xampp\htdocs\teste\teste.php:4
Stack trace:
#0 [internal function]: {closure}()
#1 {main} thrown in C:\xampp\htdocs\teste\teste.php on line 4
*/
}
});
// Proprositalmente para gerar uma exception não capturada pelo set_error_handler
$a = @$a;
try {
$b = $b;
} catch (Exception $e) {
echo $e->getMessage();
/*
Se a variável "a" tiver um arroba colocado, essa mensagem é impressa!
Nesse caso captura a exceção retorna: Undefined Variable: b
*/
}
try {
include 'teste.php';
/*
Esse include gera um E_PARSE, porém só é exibido no catch se for outros tipos de erro,
pois o register_shutdown_function é executado só quando o script é encerrado :(
Não consegui capturar com o "catch"
*/
} catch(\ErrorException $ee) {
echo $ee->getMessage(); // Esse não imprime nada, como dito acima
}
Just reinforcing what is already written in the example: There is no way to capture E_PARSER
in try/catch
(at least in this script I did, there's no way)