Pergunta

Como posso lidar com parse & fatal erros usando um costume manipulador de erro?

Foi útil?

Solução

Simples Resposta: Você não pode. Veja a manual do :

Os seguintes tipos de erro não pode ser tratadas com uma função definida pelo utilizador: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, ea maioria E_STRICT levantada no arquivo onde set_error_handler () é chamado.

Para todos os outros erros, você pode usar set_error_handler()

EDIT:

Uma vez que parece, que existem algumas discussões sobre este tema, no que diz respeito ao uso de register_shutdown_function, devemos ter um olhar para a definição de manipulação: Para mim, a manipulação um meio de erro captura o erro e reagindo de uma forma que é "agradável" para o usuário e os dados subjacentes (bancos de dados, arquivos, serviços web, etc.).

Usando register_shutdown_function você não pode lidar com um erro de dentro do código onde foi chamado, ou seja, o código seria ainda parar de trabalhar no ponto onde o erro ocorre. Você pode, no entanto, apresentar ao usuário uma mensagem de erro em vez de uma página em branco, mas você não pode, por exemplo, reverter qualquer coisa que seu código fez antes de falhar.

Outras dicas

Na verdade, você pode lidar com análise e erros fatais. É verdade que a função de manipulador de erro que você definiu com set_error_handler () não será chamado. A maneira do fazer é através da definição de uma função de paragem com register_shutdown_function (). Aqui está o que eu trabalhar no meu site:

Arquivo prepend.php (este arquivo será anexado a todos os scripts PHP automaticamente). Veja abaixo para obter dicas sobre prepending arquivos para PHP.

set_error_handler("errorHandler");
register_shutdown_function("shutdownHandler");

function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context)
{
$error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line;
switch ($error_level) {
    case E_ERROR:
    case E_CORE_ERROR:
    case E_COMPILE_ERROR:
    case E_PARSE:
        mylog($error, "fatal");
        break;
    case E_USER_ERROR:
    case E_RECOVERABLE_ERROR:
        mylog($error, "error");
        break;
    case E_WARNING:
    case E_CORE_WARNING:
    case E_COMPILE_WARNING:
    case E_USER_WARNING:
        mylog($error, "warn");
        break;
    case E_NOTICE:
    case E_USER_NOTICE:
        mylog($error, "info");
        break;
    case E_STRICT:
        mylog($error, "debug");
        break;
    default:
        mylog($error, "warn");
}
}

function shutdownHandler() //will be called when php script ends.
{
$lasterror = error_get_last();
switch ($lasterror['type'])
{
    case E_ERROR:
    case E_CORE_ERROR:
    case E_COMPILE_ERROR:
    case E_USER_ERROR:
    case E_RECOVERABLE_ERROR:
    case E_CORE_WARNING:
    case E_COMPILE_WARNING:
    case E_PARSE:
        $error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line'];
        mylog($error, "fatal");
}
}

function mylog($error, $errlvl)
{
...do whatever you want...
}

PHP irá chamar a função errorHandler () se ele pega um erro em qualquer um dos scripts. Se as forças de erro do script para desligar imediatamente, o erro é tratado pela função ShutdownHandler ().

Isso está funcionando no site eu tenho em desenvolvimento. Eu ainda não testado-lo em produção. Mas ele está pegando todos os erros que eu encontro enquanto desenvolvê-lo.

Eu acredito que há um risco de pegar o mesmo erro duas vezes, uma por cada função. Isso pode acontecer se um erro que eu estou lidando na função ShutdownHandler () também foi pego por errorHandler function ().

TODO de:

1 - Eu preciso trabalhar em uma melhor função log () para erros elegantemente manipular. Porque eu ainda estou em desenvolvimento, estou basicamente log de erro para um banco de dados e ecoando-lo para a tela.

2 -. Implementar manipulação de erro para todas as chamadas de MySQL

3 -. Implementar manipulação de erro para o meu código javascript

NOTAS IMPORTANTES:

1 - Eu estou usando o seguinte linha no meu php.ini para preceder automaticamente o script acima para todos os scripts PHP:

auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"

funciona bem.

2 - Estou registrando e resolver todos os erros, incluindo erros E_STRICT. Eu acredito no desenvolvimento de um código limpo. Durante o desenvolvimento, o meu arquivo php.ini tem as seguintes linhas:

track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0

Quando vou ao vivo, vou mudar display_errors a 0 para reduzir o risco dos meus usuários vejam mensagens de erro feio PHP.

Espero que isso ajude alguém.

Você pode acompanhar esses erros usando código como este:

(erros de análise só pode ser pego se eles ocorrem em outros arquivos de script via include() ou require(), ou por colocar esse código em um auto_prepend_file como outras respostas mencionado.)

function shutdown() {
    $isError = false;

    if ($error = error_get_last()){
    switch($error['type']){
        case E_ERROR:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
        case E_USER_ERROR:
            $isError = true;
            break;
        }
    }

    if ($isError){
        var_dump ($error);//do whatever you need with it
    }
}

register_shutdown_function('shutdown');

A partir dos comentários PHP.net na página http: / /www.php.net/manual/en/function.set-error-handler.php

Eu percebi que algumas pessoas aqui mencionadas que você não pode capturar erros de análise (tipo 4, E_PARSE). Isso não é verdade. Aqui está como eu faço. Espero que isso ajude alguém.

1) Crie um arquivo "auto_prepend.php" na raiz web e adicionar o seguinte:

<?php 
register_shutdown_function('error_alert'); 

function error_alert() 
{ 
        if(is_null($e = error_get_last()) === false) 
        { 
                mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true)); 
        } 
} 
?> 

2) Em seguida, adicione "php_value auto_prepend_file /www/auto_prepend.php" para o seu arquivo .htaccess na raiz web.

  • Certifique-se de alterar o endereço de e-mail e o caminho para o arquivo.

Da minha experiência, você pode pegar todos os tipos de erros, esconder a mensagem de erro padrão e exibir uma mensagem de erro do seu próprio (se você quiser). Abaixo estão listadas as coisas que você precisa.

1) Um script inicial nível / top, vamos chamá-lo index.php onde armazenar você costume funções de manipulador de erro. manipuladores de função de erro personalizada deve ficar no topo para que eles capturar erros abaixo deles, por "abaixo" Quero dizer em arquivos inclued.

2) A suposição de que este script de cima é livre de erros deve ser verdade! isto é muito importante, você não pode pegar erros fatais no index.php quando a sua função de manipulador de erro personalizada é encontrado em index.php.

3) directivas PHP (também deve ser encontrada em index.php) set_error_handler("myNonFatalErrorHandler"); #in fim de detectar erros não fatais register_shutdown_function('myShutdown'); #in fim de detectar erros fatais fim ini_set('display_errors', false); #in para esconder erros mostrados para o usuário por php ini_set('log_errors',FALSE); #assuming nós registramos os erros nossos eus ini_set('error_reporting', E_ALL); #We como para relatar todos os erros

enquanto na produção (se não me engano) podemos deixar ini_set('error_reporting', E_ALL); como é, a fim de ser capaz de log de erro, no mesmo ini_set('display_errors', false); tempo irá certificar-se que nenhum erro é exibida para o usuário.

Quanto ao conteúdo das duas funções que eu estou falando, myNonFatalErrorHandler e myShutdown, eu não colocar detalhou o conteúdo aqui, a fim de manter as coisas simples. Além disso, os outros visitantes deram um monte de exemplos. Eu só mostrar uma idéia muito simples.

function myNonFatalErrorHandler($v, $m, $f, $l, $c){
 $some_logging_var_arr1[]="format $v, $m, $f, ".$err_lvl[$l].", $c the way you like";
 //You can display the content of $some_logging_var_arr1 at the end of execution too.
}

function myShutdown()
{
  if( ($e=error_get_last())!==null ){
      $some_logging_var_arr2= "Format the way you like:". $err_level[$e['type']].$e['message'].$e['file'].$e['line'];
  }
//display $some_logging_var_arr2 now or later, e.g. from a custom session close function
}

como por US $ err_lvl pode ser:

$err_lvl = array(E_ERROR=>'E_ERROR', E_CORE_ERROR=>'E_CORE_ERROR', E_COMPILE_ERROR=>'E_COMPILE_ERROR', E_USER_ERROR=>'E_USER_ERROR', E_PARSE=>'E_PARSE', E_RECOVERABLE_ERROR=>'E_RECOVERABLE_ERROR', E_WARNING=>'E_WARNING', E_CORE_WARNING=>'E_CORE_WARNING', E_COMPILE_WARNING=>'E_COMPILE_WARNING',
E_USER_WARNING=>'E_USER_WARNING', E_NOTICE=>'E_NOTICE', E_USER_NOTICE=>'E_USER_NOTICE',E_STRICT=>'E_STRICT');

O script com o erro de análise é sempre interrompida e não pode ser manipulado. Então, se o script é chamado diretamente ou por incluem / exigem, não há nada que você pode fazer. Mas se for chamado pelo AJAX, Flash ou qualquer outra forma, há é uma solução alternativa como detectar erros de análise.

Eu precisava disso para lidar com roteiro swfupload. Swfupload é um flash que upload de arquivos alças e toda vez que arquivo é carregado, ele chama manipulação PHP script para filedata punho - mas não há saída do navegador, de modo que o script de manipulação de PHP precisa essas configurações para fins de depuração:

  • advertências e avisos ob_start (); no teor de início e armazenar em sessão ob_get_contents (); no final do script manipulação: Isso pode ser exibido no navegador por outro script
  • erros fatais register_shutdown_function () para definir a sessão com o mesmo truque como acima
  • erros de análise se os ob_get_contents () está localizado no final do script manuseio e erro de análise ocorreu antes, a sessão não foi preenchido (ele é nulo). O script de depuração pode manipulá-lo desta maneira: if(!isset($_SESSION["swfupload"])) echo "parse error";

Nota 1 meio null is not set para isset()

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top