Exibindo página de erro personalizada em PHP para erros que não podem ser capturados por set_error_handler

Gostaria de descartar uma página parcialmente renderizada e mostrar uma página de erro em PHP.

Eu já sei sobre set_error_handler () , mas só pode capturar certos tipos de erros . Gostaria de saber como mostrar uma página de erro quando um tipo de erro que não pode ser preso por set_error_handler () é gerado.

Infelizmente, parece que o seguinte código, quando executado com PHP 5.3.2 no Apache 2.2, não faz o que eu esperaria que ele fizesse:

<?php // Start the output buffer ob_start(); // Output something into the buffer. // I only want this to be displayed if I call one of the // ob_flush functions or echo the buffer myself later. echo "yep"; // Call a function I know not to exist in order to raise // an error which cannot be trapped by set_error_handler() // and would, if display_errors was On, output "Fatal // error: Call to undefined function fwee()..." function_which_does_not_exist(); // This will never be executed. $out = ob_get_clean(); 

A saída do script é:

 yep 

Considerando que espero que ele não saia nada (ou use informações de erro e apenas informações de erro se display_errors () estiver ativado).

Tenho confirmado o uso do LiveHTTPHeaders que o PHP 5.3.2 envia um erro de 500 para o navegador quando o display_errors está desativado (e um 200 quando está ligado) usando a versão do apache fornecida pelo MacPorts, mas só custam 200s ao usar o PHP 5.3. 1 no XAMPP.

Eu tentei configurar o ErrorDocument 500 “teste” na configuração do apache (confirmado para trabalhar fazendo o mesmo para 404), mas o PHP nunca mostra o erro personalizado, mesmo quando o conteúdo inteiro do script é apenas um header('HTTP/1.1 500 Internal Server Error');

Não tenho certeza do que mais fazer para garantir que uma página parcialmente renderizada seja substituída por um erro simples.

Também posso confirmar que isso acontece na estrutura Yii. Se eu editar a vista para a página “sobre” na demo do blog para ter uma linha que lê , Eu recebo uma página parcialmente renderizada.

Você pode passar ob_start o nome de uma function de retorno de chamada, que é executada antes da saída ser liberada em ob_get_clean ().

Essa function de retorno de chamada costuma ser executada mesmo que ocorresse um erro na página.

Desta forma, você poderia fazer algo como isto:

  

Eu acho que a única maneira correta de fazer isso é usando o buffer de saída correto, do que você não precisa confiar no servidor específico ou no comportamento do navegador.

Melhor você usaria uma estrutura MVC para lidar com isso para você. Toda a saída é armazenada em buffer até que todos os sistemas estejam, então, quando ocorre um erro, você pode seguir outra rota, limpar o buffer atual e exibir uma boa mensagem de erro.

Você também pode usar a família de funções ob _ * ().

  • Você deve chamar ob_start () como a primeira coisa em seu script (bem, antes que qualquer saída seja gerada)
  • Instale um error_handler para buscar erros
  • Quando ocorreu um erro, limpe o buffer e reencaminhe a lógica do aplicativo para exibir uma mensagem de erro agradável e amigável

Se você falar sobre E_FATAL ou outros erros, sim, você pode pegá-los com um manipulador de erros personalizado usando set_error_handler ().

Tudo o que você precisa adicionar é uma function de desligamento.

 // Set the error handler set_error_handler(array('error', 'handler')); // Catch E_FATAL errors too! register_shutdown_function(array('error', 'catch_fatal')); // Set the exception handler set_exception_handler(array('error', 'exception')); // Manually return a new exception function catch_fatal() { if($e=error_get_last())Error::exception(new ErrorException($e['message'],$e['type'],0,$e['file'],$e['line'])); } 

Dê uma olhada em http://micromvc.com ou http://kohanaphp.com/ para ver como é feito.

Uma pergunta antiga, mas para o registro, eu sugeriria evitar essa questão em vez de lidar com isso.

Minha própria abordagem é criar a resposta em um object de resposta ao invés de ecoá-lo à medida que você acompanha e apenas ecoar a saída depois que a resposta completa foi processada sem erro. Isso requer um sistema de modelo que analise seu modelo e cria sua resposta em uma seqüência de caracteres, em contraste com um modelo clássico do PHP que faz eco da saída dos seus espaços reservados.

Desta forma, você evita totalmente o gerenciamento de crufty do PHP do cache de saída em estados de erro.