8
My question is this::
PHP has a great feature that lets you convert errors that can occur in an application into Exceptions
. This can be done through 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 "error capture" works perfectly for errors like E_NOTICE
, E_WARNING
etc... However, when a Parse Error (E_PARSE
), the set_error_handler
is not able to capture him.
I managed to (more or less) make this capture of E_PARSE
through function register_register_shutdown_function
(it executes a function when php ends the script, even if there is an interruption of execution on account of E_PARSE
) in combination with the function error_get_last
.
- I would like to know how to proceed to make this operation, so
that occurs similarly in the capture of errors with the
set_error_handler
. - How to proceed if display on the screen only the error (and not codes
before execution). I will have to use a
ob_start
combined with oneob_end_clean
inside the error "catcher"?
I’ll tell you in advance:
To say that there is no way to do this is a lie, because the Laravel 4
can perfectly transform the E_PARSE
except also!
Updating
At user’s request @gmsantos, I am posting the transformation code of E_PARSE
for ErrorException
, that I think is as close as I am wanting.
That’s what I was able to do using the register_shutdown_function
(was pretty fast, so there’s no object-oriented :) ):
<?php
ob_start();
echo 'Olá mundo';
// Por essa função, o try/catch consegue "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 the E_PARSER
in the try/catch
(at least, in this script I did, there’s no way)
Actually it’s not Laravel that does it, but its debug components. Have you tried investigating the source code of Whoops (Laravel 4) or symfony/Debug (Laravel 5)?
– gmsantos
Now that I know who is responsible (according to your information, @gmsantos), I will give a search yes. Thanks!
– Wallace Maxters
if you find the post answer here for us please ;)
– gmsantos
see this method in Whoops: https://github.com/filp/whoops/blob/9e1ffa25c32db969b6ce0db73290ea272d896b11/src/Whoops/Run.php#L331 . I think it’s something like you said, manipulating the output buffer.
– gmsantos
I really like PHP. But if it was a fully object-oriented (and more organized) language, I wouldn’t have to do so many paranauese (read "gambiarras" for some cases), to be able to do something that in other languages is much simpler to do!
– Wallace Maxters
PHP: love it or let it :) . The language is constantly evolving and a lot can change (read HHMV, Hack and PHPNG)
– gmsantos
rsrsrsrsrsrsrs! is just a vent! I won’t let PHP not, it pays my salary.
– Wallace Maxters
ve this comment on the PHP website should help your implementation http://php.net/manual/en/function.set-error-handler.php#84345
– Adir Kuhn