Tratamento de erros de PHP: die () Vs trigger_error () Vs throw Exception


119

Em relação ao tratamento de erros em PHP - pelo que sei, existem 3 estilos:

  1. die()ou exit()estilo:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) {
     die('Could not connect: ' . mysql_error());
    }
  2. throw Exception estilo:

     if (!function_exists('curl_init')) {
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        }
  3. trigger_error() estilo:

    if(!is_array($config) && isset($config)) {
            trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
        }

Agora, no manual do PHP, todos os três métodos são usados.

  • O que eu quero saber é qual estilo devo preferir e por quê?

  • Essas 3 diminuem nas substituições uma da outra e, portanto, podem ser usadas alternadamente?

Ligeiramente OT: Sou só eu ou todo mundo acha que as opções de tratamento de erros do PHP são demais a ponto de confundir os desenvolvedores de php?


4
Estes não são "estilos". Eles são recursos de linguagem diferentes. Para finalidades diferentes.
mario de

11
@mario: quais são as diferentes finalidades recuadas ? Por favor me esclareça :)
CuriousMind

Você colocou a questão de uma maneira excelente. obrigado por perguntar
Contador م

Respostas:


86

O primeiro nunca deve ser usado no código de produção, pois está transportando informações irrelevantes para os usuários finais (um usuário não pode fazer nada sobre "Não é possível conectar ao banco de dados" ).

Você lança exceções se sabe que, em um determinado ponto crítico do código, seu aplicativo pode falhar e você deseja que seu código se recupere em vários níveis de chamada.

trigger_error()permite um relatório de erros de baixa granularidade (usando diferentes níveis de mensagens de erro) e você pode ocultar esses erros dos usuários finais (usando set_error_handler()), mas ainda exibi-los durante o teste.

Também trigger_error()pode produzir mensagens não fatais importantes durante o desenvolvimento, que podem ser suprimidas no código de produção usando um manipulador de erros personalizado. Você também pode produzir erros fatais ( E_USER_ERROR), mas eles não são recuperáveis. Se você disparar um deles, a execução do programa será interrompida nesse ponto. É por isso que, para erros fatais, devem ser usadas exceções. Dessa forma, você terá mais controle sobre o fluxo de seu programa:

// Example (pseudo-code for db queries):

$db->query('START TRANSACTION');

try {
    while ($row = gather_data()) {
       $db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
    }
    $db->query('COMMIT');
} catch(Exception $e) {
    $db->query('ROLLBACK');
}

Aqui, se gather_data()simplesmente coaxar (usando E_USER_ERRORou die()) houver uma chance, as INSERTdeclarações anteriores teriam entrado em seu banco de dados, mesmo se não desejadas e você não teria controle sobre o que vai acontecer a seguir.


2
então fora de trigger_error()e lançando exceções: qual devo usar e quando?
CuriousMind de

@Gaurish Veja o exemplo adicionado sobre isso.
Linus Kleen

2
Depois de ler seu exemplo, acho que agora entendo melhor o propósito por trás de lançar exceção. Obrigado :)
CuriousMind

1
@Pacerier Isso depende da configuração do servidor, na verdade. Um sistema pode ser configurado para autocommit por padrão, portanto, o explícito ROLLBACK. Este exemplo de pseudocódigo cobre os dois casos: servidores que não estão configurados para confirmação automática (a COMMITinstrução é necessária) e aqueles que o fazem.
Linus Kleen

1
@LinusKleen, o autocommit não é desativado quando executamos a linha query('START TRANSACTION');?
Pacerier

10

Eu geralmente uso a primeira forma de depuração simples no código de desenvolvimento. Não é recomendado para produção. A melhor maneira é lançar uma exceção, que você pode capturar em outras partes do programa e fazer algum tratamento de erros.

Os três estilos não são substitutos imediatos uns dos outros. O primeiro não é um erro, mas apenas uma maneira de interromper o script e gerar algumas informações de depuração para você analisar manualmente. O segundo não é um erro em si, mas será convertido em um erro se você não detectá-lo. O último está provocando um erro real no motor do PHP que será tratado de acordo com a configuração do seu ambiente PHP (em alguns casos mostrado ao usuário, em outros casos apenas logado em um arquivo ou nem salvo).


1
O que acontece quando a exceção é lançada, mas não detectada? isso vai causar um erro fatal, eu acho. E com a trigger_error()mesma coisa acontece. então qual é a diferença?
CuriousMind

4
A diferença é que você pode capturar a exceção e tratá-la da maneira que desejar.
Emil Vikström de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.