Puedo usar set_error_handler()
para detectar la mayoría de los errores de PHP, pero no funciona para E_ERROR
errores fatales ( ), como llamar a una función que no existe. ¿Hay otra forma de detectar estos errores?
Estoy tratando de llamar mail()
a todos los errores y estoy ejecutando PHP 5.2.3.
php
fatal-error
demasiado php
fuente
fuente
Respuestas:
Registre errores fatales utilizando el
register_shutdown_function
, que requiere PHP 5.2+:Deberá definir las funciones
error_mail
yformat_error
. Por ejemplo:Use Swift Mailer para escribir la
error_mail
función.Ver también:
fuente
mail("[email protected]", "My Site: FATAL ERROR", "Details: " . $errno . ' ' . $errstr . ' ' . $errfile . ' ' . $errline);
Se me ocurrió esta solución (PHP 5.2.0+):
Se definen diferentes tipos de error en Constantes predefinidas .
fuente
If an error handler (see set_error_handler ) successfully handles an error then that error will not be reported by this function.
"register_shutdown_function()
debe ser anterior a cualquier error fatal.use_1T_memory(); /* memory exhausted error here! */ register_shutdown_function('shutDownFunction');
No funcionará como se esperaba.PHP no proporciona medios convencionales para atrapar y recuperarse de errores fatales. Esto se debe a que el procesamiento no debe recuperarse normalmente después de un error fatal. La cadena que coincide con un búfer de salida (como sugiere la publicación original, la técnica descrita en PHP.net) es definitivamente desaconsejada. Es simplemente poco confiable.
Llamar a la función mail () desde un método de manejo de errores también resulta problemático. Si tuviera muchos errores, su servidor de correo estaría cargado de trabajo y podría encontrarse con una bandeja de entrada retorcida. Para evitar esto, puede considerar ejecutar un cron para escanear registros de errores periódicamente y enviar notificaciones en consecuencia. También es posible que desee analizar el software de monitoreo del sistema, como Nagios .
Para hablar un poco sobre el registro de una función de apagado:
Es cierto que puede registrar una función de apagado, y esa es una buena respuesta.
El punto aquí es que normalmente no deberíamos intentar recuperarnos de errores fatales, especialmente no mediante el uso de una expresión regular contra su búfer de salida. Estaba respondiendo a la respuesta aceptada , que se vinculaba con una sugerencia en php.net que desde entonces ha sido modificada o eliminada.
Esa sugerencia fue usar una expresión regular contra el búfer de salida durante el manejo de excepciones, y en el caso de un error fatal (detectado por la coincidencia con cualquier texto de error configurado que pueda esperar), intente hacer algún tipo de recuperación o procesamiento continuo. Esa no sería una práctica recomendada (creo que es por eso que no puedo encontrar la sugerencia original también. O lo estoy pasando por alto o la comunidad de php la rechazó).
Vale la pena señalar que las versiones más recientes de PHP (alrededor de 5.1) parecen llamar a la función de apagado antes, antes de que se invoque la devolución de llamada de búfer de salida. En la versión 5 y anteriores, ese orden era el inverso (la devolución de llamada de la memoria intermedia de salida fue seguida por la función de apagado). Además, desde aproximadamente 5.0.5 (que es mucho anterior a la versión 5.2.3 del interlocutor), los objetos se descargan mucho antes de que se llame a una función de apagado registrada, por lo que no podrá confiar en sus objetos en memoria para hacer mucho de cualquier cosa.
Por lo tanto, registrar una función de apagado está bien, pero el tipo de tareas que debe realizar una función de apagado probablemente se limite a un puñado de procedimientos de apagado suaves.
La clave aquí es solo algunas palabras de sabiduría para cualquiera que se tope con esta pregunta y vea el consejo en la respuesta originalmente aceptada. No regexes tu búfer de salida.
fuente
Bueno, parece posible detectar errores fatales de otra manera :)
fuente
Los errores fatales o errores fatales recuperables Ahora lanzan casos de
Error
en PHP 7 o versiones superiores . Como cualquier otra excepción, losError
objetos se pueden atrapar usando untry/catch
bloque.Ejemplo:
https://3v4l.org/67vbk
O puede usar la
Throwable
interfaz para capturar todas las excepciones.Ejemplo:
https://3v4l.org/Br0MG
Para más información: http://php.net/manual/en/language.errors.php7.php
fuente
Fatal error: Trait 'FailedTrait' not found in
cuando se usaReflectionClass
?include "filename.php"
en su lugar, en eltry
bloque, luego elThrowable
bloque catch al menos funcionaParseError
.¡Desarrollé una forma de detectar todos los tipos de error en PHP (casi todos)! ¡No estoy seguro acerca de E_CORE_ERROR (creo que no funcionará solo para ese error)! Pero, para otros errores fatales (E_ERROR, E_PARSE, E_COMPILE ...) funciona bien usando solo una función de controlador de errores. Ahí va mi solución:
Ponga el siguiente código en su archivo principal (index.php):
fuente
No puede detectar / manejar errores fatales, pero puede registrarlos / informarlos. Para una depuración rápida, modifiqué una respuesta a este código simple
fuente
No puede lanzar una excepción dentro de una función de apagado registrada como esa:
Pero puede capturar y redirigir la solicitud a otra página.
fuente
Si está utilizando PHP> = 5.1.0 Simplemente haga algo como esto con la clase ErrorException:
fuente
Buena solución encontrada en Zend Framework 2:
Esta clase le permite comenzar lo específico a
ErrorHandler
veces si lo necesita. Y luego también puede detener el controlador.Use esta clase, por ejemplo, así:
Enlace al código de clase completo:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ErrorHandler.php
Una solución quizás mejor es la de Monolog :
Enlace al código de clase completo:https://github.com/Seldaek/monolog/blob/master/src/Monolog/ErrorHandler.php
También puede manejar FATAL_ERRORS usando la
register_shutdown_function
función. De acuerdo con esta clase, un FATAL_ERROR es uno de los siguientesarray(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)
.fuente
Necesito manejar errores fatales para que la producción muestre en su lugar una salida HTML no disponible de servicio 503 de estilo estático . Este es sin duda un enfoque razonable para "detectar errores fatales". Esto es lo que he hecho:
Tengo una función personalizada de manejo de errores "error_handler" que mostrará mi página HTML "503 servicio no disponible" en cualquier E_ERROR, E_USER_ERROR, etc. Esto ahora se llamará en la función de apagado, detectando mi error fatal,
en mi función personalizada error_handler, si el error es E_ERROR, E_USER_ERROR, etc. También llamo
@ob_end_clean();
para vaciar el búfer, eliminando así el mensaje de "error fatal" de PHP.Tome nota importante de las estrictas funciones de comprobación y
@
silenciamiento de isset () ya que no queremos que nuestros scripts error_handler generen errores.Al seguir de acuerdo con Keparo, detectar errores fatales no cumple con el propósito del "error FATAL", por lo que no está destinado a que realices un procesamiento posterior. No ejecute ninguna función de correo () en este proceso de apagado, ya que seguramente hará una copia de seguridad del servidor de correo o de su bandeja de entrada. En su lugar, registre estas ocurrencias en el archivo y programe un trabajo cron para encontrar estos archivos error.log y envíelos por correo a los administradores.
fuente
PHP tiene errores fatales detectables. Se definen como E_RECOVERABLE_ERROR. El manual de PHP describe un E_RECOVERABLE_ERROR como:
Puede "atrapar" estos errores "fatales" utilizando set_error_handler () y buscando E_RECOVERABLE_ERROR. Me resulta útil lanzar una excepción cuando se detecta este error, entonces puede usar try / catch.
Esta pregunta y respuesta proporcionan un ejemplo útil: ¿Cómo puedo detectar un "error fatal detectable" en las sugerencias de tipo PHP?
Los errores E_ERROR, sin embargo, pueden manejarse, pero no recuperarse ya que el motor está en un estado inestable.
fuente
Aquí hay un buen truco para obtener el método actual error_handler =)
También quiero señalar que si llamas
PHP deja de mostrar el error. De lo contrario, el texto del error se enviará al cliente antes de su controlador de errores.
fuente
Como la mayoría de las respuestas aquí son innecesariamente detalladas, aquí está mi versión no fea de la respuesta más votada:
fuente
Realmente no. Los errores fatales se llaman así, porque son fatales. No puedes recuperarte de ellos.
fuente
Desarrollé esta función para hacer posible el código "sandbox" que podría causar un error fatal. Dado que las excepciones lanzadas desde el cierre
register_shutdown_function
no se emiten desde la pila de llamadas de error pre-fatal, me veo obligado a salir después de esta función para proporcionar una forma uniforme de usarla.fuente
Hay ciertas circunstancias en las que se deben detectar incluso los errores fatales (es posible que deba limpiar un poco antes de salir con gracia y no simplemente morir ...).
He implementado un enlace pre_system en mis aplicaciones CodeIgniter para que pueda recibir mis errores fatales a través de correos electrónicos, y esto me ayudó a encontrar errores que no se informaron (o se informaron después de que se corrigieron, como ya sabía sobre ellos :)).
Sendemail comprueba si el error ya se ha informado para que no le envíe spam con errores conocidos varias veces.
fuente