Necesito detectar algunas advertencias que se lanzan desde algunas funciones nativas de php y luego manejarlas.
Específicamente:
array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] )
Lanza una advertencia cuando falla la consulta DNS.
try
/ catch
no funciona porque una advertencia no es una excepción.
Ahora tengo 2 opciones:
set_error_handler
parece excesivo porque tengo que usarlo para filtrar cada advertencia en la página (¿es esto cierto?);Ajuste el informe / visualización de errores para que estas advertencias no se repitan en la pantalla, luego verifique el valor de retorno; si es así
false
, no se encuentran registros para el nombre de host.
¿Cuál es la mejor práctica aquí?
php
error-handling
try-catch
usuario121196
fuente
fuente
Respuestas:
Establecer y restaurar el controlador de errores
Una posibilidad es configurar su propio controlador de errores antes de la llamada y restaurar el controlador de errores anterior más adelante con
restore_error_handler()
.Podría aprovechar esta idea y escribir un controlador de errores reutilizable que registre los errores por usted.
Convertir errores en excepciones
Puede usar
set_error_handler()
y laErrorException
clase para convertir todos los errores de php en excepciones.Lo importante a tener en cuenta al usar su propio controlador de errores es que omitirá la
error_reporting
configuración y pasará todos los errores (avisos, advertencias, etc.) a su controlador de errores. Puede establecer un segundo argumentoset_error_handler()
para definir qué tipos de error desea recibir o acceder a la configuración actual utilizando... = error_reporting()
el controlador de errores.Suprimiendo la advertencia
Otra posibilidad es suprimir la llamada con el operador @ y verificar el valor de retorno de
dns_get_record()
después. Pero desaconsejaría esto, ya que los errores / advertencias se activan para ser manejados, no para ser suprimidos.fuente
La solución que realmente funciona es establecer un controlador de errores simple con
E_WARNING
parámetros, de esta manera:fuente
callable
se puede usar aquí anónimo en lugar de una cadena con declaración de funcióntrow new \Exception($errstr, $errno);
dentro de lawarning_handler
función. Gracias.Tenga cuidado con el
@
operador : mientras suprime las advertencias, también elimina los errores fatales. Pasé mucho tiempo depurando un problema en un sistema donde alguien había escrito@mysql_query( '...' )
y el problema era que el soporte de mysql no estaba cargado en PHP y arrojó un error fatal silencioso. Será seguro para aquellas cosas que son parte del núcleo de PHP, pero úselo con cuidado.No hay más resultados: ¡buena suerte para depurar esto!
Esta vez podemos ver por qué falló.
fuente
Quería intentar / detectar una advertencia, pero al mismo tiempo mantener el registro habitual de advertencia / error (por ejemplo, en
/var/log/apache2/error.log
); por lo cual el manejador tiene que regresarfalse
. Sin embargo, dado que la instrucción "lanzar nuevo ..." básicamente interrumpe la ejecución, uno tiene que hacer el truco de "envolver en función", que también se analiza en:¿Hay una forma estática de lanzar una excepción en php
O, en resumen:
EDITAR: después de una inspección más cercana, resulta que no funciona: "
return false && throwErrorException ...
" básicamente, no arrojará la excepción, y simplemente ingresará al registro de errores; eliminar la "false &&
" parte, como en "return throwErrorException ...
", hará que el lanzamiento de excepción funcione, pero luego no se registrará en el error_log ... Sin embargo, aún lo mantendré publicado, ya que no he visto este comportamiento documentado en otro lugar.fuente
Probablemente debería intentar deshacerse de la advertencia por completo, pero si eso no es posible, puede anteponer la llamada con @ (es decir, @dns_get_record (...)) y luego usar cualquier información que pueda averiguar si ocurrió la advertencia o no.
fuente
Normalmente, nunca debe usar @ a menos que esta sea la única solución. En ese caso específico, la función dns_check_record debe usarse primero para saber si existe el registro.
fuente
La combinación de estas líneas de código en torno a una
file_get_contents()
llamada a una URL externa me ayudó a manejar advertencias como " no se pudo abrir la transmisión: la conexión agotó el tiempo de espera " mucho mejor:Esta solución también funciona dentro del contexto del objeto. Podrías usarlo en una función:
fuente
Si
dns_get_record()
falla, debería regresarFALSE
, para que pueda suprimir la advertencia con@
y luego verificar el valor de retorno.fuente
intente comprobar si devuelve algún valor booleano, simplemente puede ponerlo como condición. Encontré esto con el oci_execute (...) que estaba devolviendo alguna violación con mis claves únicas.
fuente
Carpeta Estructura
CustomException.php
simplemente incluya el archivo anterior en su archivo de secuencia de comandos como este
index.php
fuente
Solo recomendaría usar @ para suprimir las advertencias cuando se trata de una operación directa (por ejemplo, $ prop = @ ($ high / ($ width - $ depth)); para omitir la división por cero advertencias). Sin embargo, en la mayoría de los casos, es mejor manejarlo.
fuente