Eu preciso pegar alguns avisos sendo lançados a partir de algumas funções nativas do php e depois lidar com eles.
Especificamente:
array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] )
Emite um aviso quando a consulta DNS falha.
try
/ catch
não funciona porque um aviso não é uma exceção.
Agora tenho 2 opções:
set_error_handler
parece exagero porque tenho que usá-lo para filtrar todos os avisos da página (isso é verdade?);Ajuste o relatório / exibição de erros para que esses avisos não sejam exibidos na tela e verifique o valor de retorno; se for
false
, nenhum registro será encontrado para o nome do host.
Qual é a melhor prática aqui?
php
error-handling
try-catch
user121196
fonte
fonte
Respostas:
Definir e restaurar manipulador de erros
Uma possibilidade é definir seu próprio manipulador de erros antes da chamada e restaurar o manipulador de erros anterior posteriormente com
restore_error_handler()
.Você pode desenvolver essa ideia e escrever um manipulador de erros reutilizável que registre os erros para você.
Transformando erros em exceções
Você pode usar
set_error_handler()
e aErrorException
classe para transformar todos os erros de php em exceções.O importante a ser observado ao usar seu próprio manipulador de erros é que ele ignorará a
error_reporting
configuração e passará todos os erros (avisos, avisos etc.) para o manipulador de erros. Você pode definir um segundo argumentoset_error_handler()
para definir quais tipos de erro deseja receber ou acessar a configuração atual usando... = error_reporting()
dentro do manipulador de erros.Suprimindo o aviso
Outra possibilidade é suprimir a chamada com o operador @ e verificar o valor de retorno
dns_get_record()
posteriormente. Mas eu aconselho isso, pois os erros / avisos são acionados para serem manipulados, não para serem suprimidos.fonte
A solução que realmente funciona acabou por definir um manipulador de erros simples com o
E_WARNING
parâmetro, da seguinte maneira:fonte
callable
pode ser usado aqui em vez de string com declaração da funçãotrow new \Exception($errstr, $errno);
dentro dawarning_handler
função. Obrigado.Tenha cuidado com o
@
operador - enquanto suprime avisos, também suprime erros fatais. Passei muito tempo depurando um problema em um sistema em que alguém havia escrito@mysql_query( '...' )
e o problema era que o suporte ao mysql não era carregado no PHP e gerava um erro fatal silencioso. Será seguro para aquelas coisas que fazem parte do núcleo do PHP, mas por favor, usá-lo com cuidado.Não há mais saída - boa sorte depurando isso!
Desta vez, podemos ver por que ele falhou.
fonte
Eu queria tentar / capturar um aviso, mas ao mesmo tempo manter o log de aviso / erro usual (por exemplo, in
/var/log/apache2/error.log
); para o qual o manipulador deve retornarfalse
. No entanto, como a instrução "throw new ..." basicamente interrompe a execução, é necessário executar o truque "wrap in function", também discutido em:Existe uma maneira estática de lançar exceção em php
Ou, resumidamente:
EDIT: após uma inspeção mais minuciosa, verifica-se que não funciona: o "
return false && throwErrorException ...
" basicamente não lançará a exceção e apenas fará o logon no log de erros; remover afalse &&
parte " ", como em "return throwErrorException ...
", fará com que a exceção funcione, mas não fará logon no error_log ... Eu ainda manteria isso informado, pois não vi esse comportamento documentado em outro lugar.fonte
Você provavelmente deve tentar se livrar completamente do aviso, mas se isso não for possível, você pode anexar a chamada com @ (por exemplo, @dns_get_record (...)) e, em seguida, usar todas as informações para descobrir se o aviso ocorreu. ou não.
fonte
Normalmente você nunca deve usar @, a menos que seja a única solução. Nesse caso específico, a função dns_check_record deve ser usada primeiro para saber se o registro existe.
fonte
A combinação dessas linhas de código em torno de uma
file_get_contents()
chamada para um URL externo me ajudou a lidar com avisos como " falha ao abrir o fluxo: a conexão expirou " muito melhor:Essa solução também funciona no contexto do objeto. Você poderia usá-lo em uma função:
fonte
Se
dns_get_record()
falhar, ele deve retornarFALSE
, para que você possa suprimir o aviso com@
e depois verificar o valor de retorno.fonte
tente verificar se ele retorna algum valor booleano, então você pode simplesmente colocá-lo como uma condição. Encontrei isso com o oci_execute (...), que estava retornando alguma violação com minhas chaves exclusivas.
fonte
FolderStructure
CustomException.php
basta incluir o arquivo acima em seu arquivo de script como este
index.php
fonte
Eu recomendaria apenas usar @ para suprimir avisos quando for uma operação direta (por exemplo, $ prop = @ ($ high / ($ width - $ depth)); para pular a divisão por zero avisos). No entanto, na maioria dos casos, é melhor lidar com isso.
fonte