Pergunta

Eu estou familiarizado com alguns dos princípios básicos, mas o que eu gostaria de saber mais sobre é quando e por que o tratamento de erros (incluindo exceções jogando) deve ser usado em PHP, especialmente em um site ao vivo ou aplicativo web. É algo que pode ser usado em demasia e se assim for, o que faz olhar overuse como? Existem casos em que não devem ser usados? Além disso, quais são algumas das preocupações de segurança comuns no que diz respeito ao tratamento de erros?

Foi útil?

Solução

Uma coisa a acrescentar ao que já foi dito é que é fundamental que você gravar quaisquer erros na sua aplicação web em um log. Desta forma, como Jeff "Coding Horror" Atwood sugere, você saberá quando os usuários estão enfrentando problemas com seu aplicativo (em vez de "pedindo-lhes o que está errado").

Para fazer isso, eu recomendo o seguinte tipo de infra-estrutura:

  • Criar uma tabela "crash" em seu banco de dados e um conjunto de classes de mensagens publicitárias para relatar erros. Eu recomendo definindo categorias para as falhas ( "bloqueio", "segurança", "erro PHP / aviso" (vs exceção), etc).
  • Em todo o seu tratamento de erros de código, certifique-se de gravar o erro. Fazendo isso de forma consistente depende de quão bem você construiu o API (acima etapa) - deve ser trivial para gravar acidentes se feito direito.

crédito Extra: às vezes, seus bloqueios serão acidentes de nível de banco de dados: isto é DB servidor para baixo, etc. Se for esse o caso, a sua infra-estrutura de registro de erros (acima) irá falhar (você não pode registrar o acidente com o DB porque o log tenta escrever para o DB). Nesse caso, eu iria escrever a lógica de failover em sua Bater invólucro de classe para qualquer

  • Envie um e-mail para o administrador, E / OU
  • registrar os detalhes do acidente a um arquivo de texto simples

Tudo isso soa como um exagero, mas acredite em mim, isso faz a diferença em saber se o seu pedido for aceite como um "estável" ou "esquisito". Essa diferença vem do fato de que todos os aplicativos começar tão esquisito / bater o tempo todo, mas os desenvolvedores que sabem sobre todos os problemas com o seu aplicativo tem a chance de realmente corrigi-lo.

Outras dicas

A grosso modo, os erros são um legado em PHP, enquanto exceções são a maneira moderna de erros do deleite. A coisa mais simples, em seguida, é a criação de um erro-manipulador, que lança uma exceção. Dessa forma, todos os erros são convertidos em exceções e, em seguida, você pode simplesmente lidar com um esquema de manipulação de erro. O código a seguir irá converter erros para exceções para você:

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);

Existem alguns casos, porém, em que o código é projetado especificamente para trabalhar com erros. Por exemplo, o método schemaValidate de DomDocument levanta advertências, ao validar um documento . Se você converter erros para exceções, ele irá parar validando após a primeira falha. Algumas vezes isto é o que você quer, mas ao validar um documento, você pode realmente deseja todas fracassos. Neste caso, você pode instalar temporariamente um erro-manipulador, que recolhe os erros. Aqui está um pequeno trecho, eu usei para o efeito:

class errorhandler_LoggingCaller {
  protected $errors = array();
  function call($callback, $arguments = array()) {
    set_error_handler(array($this, "onError"));
    $orig_error_reporting = error_reporting(E_ALL);
    try {
      $result = call_user_func_array($callback, $arguments);
    } catch (Exception $ex) {
      restore_error_handler();
      error_reporting($orig_error_reporting);
      throw $ex;
    }
    restore_error_handler();
    error_reporting($orig_error_reporting);
    return $result;
  }
  function onError($severity, $message, $file = null, $line = null) {
    $this->errors[] = $message;
  }
  function getErrors() {
    return $this->errors;
  }
  function hasErrors() {
    return count($this->errors) > 0;
  }
}

E um caso de uso:

$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
  array($doc, 'schemaValidate'),
  array($xsd_filename));
if ($validation->hasErrors()) {
  var_dump($validation->getErrors());
}

erros unhanded parar o script, que por si só é uma boa razão bastante para lidar com eles.

Geralmente você pode usar um bloco try-catch para lidar com erros

try
{
    // Code that may error
}
catch (Exception $e)
{
    // Do other stuff if there's an error
}

Se você quiser parar a mensagem de erro ou aviso aparece na página, então você pode prefixar a chamada com um sinal @ como tal.

 @mysql_query($query);

Com consultas no entanto, é geralmente uma boa idéia para fazer algo assim para que você tenha uma idéia melhor do que está acontecendo.

@mysql_query($query)
    or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');

Você deve usar Tratamento de erros nos casos em que você não tem controle explícito sobre os dados que o script está trabalhando. I tendem a usá-lo com frequência, por exemplo, em lugares como a validação de formulário. Sabendo como identificar erro lugares propensos em código requer alguma prática: Alguns dos mais comuns estão atrás de chamadas de funções que retornam um valor, ou quando se lida com os resultados de uma consulta de banco de dados. Você nunca deve assumir o retorno de uma função será o que o seu esperando, e você deve ter certeza de código em antecipação. Você não tem que usar blocos try / catch, embora eles são úteis. Um monte de vezes que você pode conviver com um simples if / verificação mais.

Erro de manipulação anda de mãos dadas com práticas de codificação seguras, como há um grande número de "erros" que não causam o script simplesmente falhar. embora não sendo estritamente sobre manipulação de erro, por si só, addedbytes tem uma série de artigos boa 4 em algumas das noções básicas de programação PHP seguro que você pode encontrar AQUI . Há uma série de outras questões aqui em stackoverflow sobre temas como mysql_real_escape_string e Expressões regulares que pode ser muito poderoso em confirmando o conteúdo de dados introduzidos pelo utilizador.

A melhor IMHO prática é usar a seguinte abordagem: 1. Criar um manipulador de erro / exceção 2. Comece-a sobre o aplicativo arranque 3. pega todos os seus erros de lá dentro

<?php

classe de depuração {

    public static setAsErrorHandler() {
         set_error_handler(array(__CLASS__, '__error_handler'));
    }

public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
       if (IN DEV) {
                print on screen
           }
           else if (IN PRO) {
                log and mail
           } 
    }

}

Debug :: setAsErrorHandler ();

?>

Ao invés de outputing o mysql_error que você pode armazená-lo em um log. Dessa forma, você pode acompanhar o erro (e você não dependem de usuários para denunciá-lo) e você pode entrar e remover o problema.

O melhor tratamento de erros é o tipo que é transparente para o usuário, deixe o seu código de resolver o problema, não há necessidade de envolver aquele sujeito usuário.

Além de tratamento de erros de imediato no seu código, você também pode fazer uso de

http://us.php.net/manual /en/function.set-exception-handler.php
e
http://us.php.net/manual/en/ function.set-error-handler.php

Acho definindo seu próprio manipulador de exceção particularmente útil. Quando ocorre uma exceção que você pode executar operações diferentes dependendo do que tipo de exceção que é.

ex: quando uma chamada mysql_connet retornos FALSE eu jogo uma new DBConnectionException(mysql_error()) e lidar com isso de maneira "especial": registrar o erro, o DB informações de conexão (host, username, password) etc e talvez até mesmo enviar e-mail a equipe de desenvolvimento notificando que algo pode ser realmente errado com o DB

Eu uso isso para complementar o tratamento de erros padrão. I wouldnt recomendar o uso excessivo dessa abordagem

supressão de erro com @ é muito lento.

Você também pode usar o Google formas de capturar e analisar exceções, sem ter que manter um banco de dados ou servidor de acesso público. Há um tutorial aqui que explica o processo.

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