2008-09-25 17 views
28

Estoy familiarizado con algunos de los conceptos básicos, pero lo que me gustaría saber es cuándo y por qué se debe usar el manejo de errores (incluyendo excepciones) en PHP, especialmente en un sitio web o en vivo aplicación ¿Es algo que se puede usar en exceso y, de ser así, cómo se ve el uso excesivo? ¿Hay casos en que no debería usarse? Además, ¿cuáles son algunas de las preocupaciones de seguridad comunes en relación con el manejo de errores?Manejo de errores en PHP

Respuesta

29

Una cosa para agregar a lo que ya se ha dicho es que es primordial que registre cualquier error en su aplicación web en un registro. De esta forma, como lo sugiere Jeff "Coding Horror" Atwood, sabrá cuándo sus usuarios tienen problemas con su aplicación (en lugar de "preguntarles qué ocurre").

Para ello, recomiendo el siguiente tipo de infraestructura:

  • Crear una tabla de "accidente" en su base de datos y un conjunto de clases de envoltura para informar de errores. Recomiendo establecer categorías para los bloqueos ("bloqueo", "seguridad", "error/advertencia PHP" (frente a excepción), etc.).
  • En todos los códigos de manejo de errores, asegúrese de registrar el error. Hacer esto consistentemente depende de qué tan bien construiste la API (paso anterior): debería ser trivial para registrar bloqueos si se hace bien.

Crédito adicional: a veces, se bloquea será accidentes a nivel de la base de datos del servidor: es decir, DB abajo, etc. Si ese es el caso, la infraestructura de registro de errores (arriba) se producirá un error (no se puede registrar la caída de el DB porque el log intenta escribir en el DB). En ese caso, me gustaría escribir la lógica de conmutación por error en su clase Crash envoltura para cualquiera

  • enviar un correo electrónico al administrador, Y/O
  • registro de los detalles del accidente a un archivo de texto plano

Todo esto suena como una exageración, pero créanme, esto hace una diferencia en si su aplicación es aceptada como "estable" o "escamosa". Esa diferencia proviene del hecho de que todas las aplicaciones comienzan como escamosas/bloqueadas todo el tiempo, pero los desarrolladores que conocen todos los problemas con sus aplicaciones tienen la oportunidad de arreglarlo realmente.

+0

Un gran consejo sea cual sea la plataforma. – Swinders

+0

Aunque el tema anterior, me gustaría aconsejar tener cuidado con el envío de un correo electrónico al administrador, ya que muchos servicios de alojamiento aceptan un límite de estos y un error en un bucle podría causar varios problemas. Estado allí sufrió eso. –

+0

2017+ ahora hay muchos productos SaaS que le ayudan a registrar errores y recibir notificaciones a través de Slack, correo electrónico, etc. sobre ellos. Simplemente busque en google el "registro de errores" y encontrará muchas, algunas con buenos niveles gratuitos para startups. – KayakinKoder

2

Los errores no manuales detienen el script, eso solo es una buena razón para manejarlos.

En general se puede utilizar un bloque try-catch para tratar los errores

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

Si desea detener el mensaje de error o advertencia que aparece en la página, entonces se puede prefijar la llamada con un signo @ como tal .

@mysql_query($query); 

con consultas sin embargo, es generalmente una buena idea para hacer algo como esto para que tenga una mejor idea de lo que está pasando.

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

¿No está utilizando la función mysql_error() un riesgo de seguridad? – VirtuosiMedia

+1

enviando mysql_error al usuario es potencialmente riesgoso. –

+0

puede tener un indicador en su aplicación web que determina si se encuentra en un entorno de prueba o en producción; en producción, no muestre el error, solo conéctelo. En prueba, haz ambas cosas. –

1

En lugar de enviar el mysql_error, puede almacenarlo en un registro. De esta forma puede rastrear el error (y no depende de que los usuarios lo denuncien) y puede ingresar y eliminar el problema.

El mejor manejo de errores es del tipo que es transparente para el usuario, deje que su código resuelva el problema, sin necesidad de involucrar a ese usuario.

2

Debe usar el Manejo de errores en los casos en que no tenga control explícito sobre los datos en los que está trabajando su script. Tiendo a usarlo con frecuencia, por ejemplo, en lugares como la validación de formularios. Saber cómo detectar los lugares propensos a errores en el código requiere cierta práctica: algunos más comunes son después de llamadas a funciones que devuelven un valor o cuando se trata de resultados de una consulta de base de datos. Nunca debe suponer que el retorno de una función será lo que espera, y debe asegurarse de programar con anticipación. No tiene que usar bloques try/catch, aunque son útiles. Muchas veces se puede salir adelante con un simple control de if/else.

El manejo de errores va de la mano con las prácticas de codificación segura, ya que hay una gran cantidad de "errores" que no causan que la secuencia de comandos simplemente se cuelgue. aunque no se trata estrictamente del manejo de errores per se, addbytes tiene una buena serie de 4 artículos sobre algunos de los aspectos básicos de la programación segura de PHP que puedes encontrar en HERE. Hay muchas otras preguntas aquí en stackoverflow sobre temas tales como mysql_real_escape_string y Regular Expressions que pueden ser muy potentes para confirmar el contenido de los datos ingresados ​​por el usuario.

1

Además de manejar los errores de inmediato en el código también se puede hacer uso de

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

Me parece fijar su propio gestor de excepciones particularmente útil. Cuando ocurre una excepción, puede realizar diferentes operaciones dependiendo del tipo de excepción que sea.

por ejemplo: cuando una llamada mysql_connet vuelve FALSE lanzo un new DBConnectionException(mysql_error()) y manejarlo de una manera "especial": registrar el error, la información de conexión DB (host, nombre de usuario, contraseña), etc y tal vez incluso un correo electrónico al equipo de desarrollo notificándoles que algo puede estar realmente mal con el DB

Lo uso para complementar el manejo de errores estándar. No recomendaría abusar de este enfoque

2

El mejor en mi humilde opinión la práctica es utilizar el siguiente enfoque: 1. crear un controlador de errores/excepción 2. iniciarlo en la aplicación puesta en marcha 3. manejar todas sus errores desde el interior hay

<?php 

clase de depuración {

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 
      } 
    } 

}

depuración :: setAsErrorHandler();

?>

22

En términos generales, los errores son un legado en PHP, mientras que las excepciones son la forma más moderna para el tratamiento de errores. Lo más simple, entonces, es configurar un controlador de errores que arroje una excepción. De esta forma, todos los errores se convierten en excepciones, y luego puede tratar simplemente con un esquema de manejo de errores.El siguiente código convertir a errores excepciones para usted:

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); 

Hay unos pocos casos, sin embargo, donde el código está diseñado específicamente para trabajar con errores. Por ejemplo, el schemaValidate method of DomDocument genera advertencias al validar un documento. Si convierte errores en excepciones, dejará de validarse después de la primera falla. Algunas veces esto es lo que desea, pero al validar un documento, es posible que realmente desee todas las fallas. En este caso, puede instalar temporalmente un controlador de errores, que recopila los errores. He aquí un pequeño fragmento, que he usado para este fin:

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; 
    } 
} 

Y un caso de uso: la supresión

$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()); 
} 
+0

+1 para obtener todos los errores en el camino de análisis – coolkid

1

de errores con @ es muy lento.

+0

Hola Chris, un poco tarde, pero ¿por qué es eso? – Industrial

+0

Esto se debe a la forma en que se construye PHP. Más sobre este tema: http://seanmonstar.com/post/909029460/php-error-suppression-performance –

0

También puede usar Formularios de Google para capturar y analizar excepciones, sin tener que mantener una base de datos o un servidor de acceso público. Hay un tutorial here que explica el proceso.