Pregunta

Estoy familiarizado con algunos de los conceptos básicos, pero me gustaría saber más sobre cuándo y por qué el manejo de errores (incluidas las excepciones de lanzamiento) se debe usar en PHP, especialmente en un sitio en vivo o una aplicación web. ¿Es algo que se puede usar en exceso y, de ser así, qué aspecto tiene el uso excesivo? ¿Hay casos en los que no se debe utilizar? Además, ¿cuáles son algunas de las preocupaciones de seguridad comunes con respecto al manejo de errores?

¿Fue útil?

Solución

Una cosa para agregar a lo que ya se dijo es que es de suma importancia que registre cualquier error en su aplicación web en un registro. De esta manera, como Jeff " Coding Horror " Atwood sugiere que sabrá cuándo sus usuarios experimentan problemas con su aplicación (en lugar de " preguntándoles qué está mal ").

Para hacer esto, recomiendo el siguiente tipo de infraestructura:

  • Crear un " bloqueo " tabla en su base de datos y un conjunto de clases de envoltura para informar errores. Recomiendo establecer categorías para los bloqueos (" bloqueo " ;, " seguridad " ;, " error / advertencia de PHP " (vs excepción), etc.).
  • En todos sus códigos de manejo de errores, asegúrese de registrar el error. Hacer esto de manera consistente depende de lo bien que haya creado la API (paso anterior): debería ser trivial para registrar bloqueos si se hace correctamente.

Crédito adicional: a veces, sus bloqueos serán bloqueos en el nivel de la base de datos: es decir, el servidor de la base de datos está inactivo, etc. el registro intenta escribir en la base de datos). En ese caso, escribiría la lógica de conmutación por error en su clase de envoltorio de Crash a cualquiera de las dos

  • enviar un correo electrónico al administrador, Y / O
  • registre los detalles del bloqueo en un archivo de texto simple

Todo esto suena como una exageración, pero créeme, esto hace una diferencia en si tu solicitud se acepta como " estable " o " escamoso " ;. Esa diferencia se debe al hecho de que todas las aplicaciones comienzan a aparecer de forma inestable / inestable todo el tiempo, pero los desarrolladores que conocen todos los problemas con su aplicación tienen la oportunidad de solucionarlo.

Otros consejos

En términos generales, los errores son un legado en PHP, mientras que las excepciones son la forma moderna de tratar los errores. Lo más simple entonces, es configurar un controlador de errores, que lanza una excepción. De esa manera, todos los errores se convierten en excepciones y, a continuación, puede tratar un solo esquema de manejo de errores. El siguiente código convertirá los errores en 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 algunos casos, sin embargo, donde el código está diseñado específicamente para trabajar con errores. Por ejemplo, el método de schemaValidate del DomDocument genera advertencias al validar un documento. Si convierte los errores en excepciones, dejará de validar después del primer error. Algunas veces esto es lo que desea, pero al validar un documento, es posible que desee faltar todas . En este caso, puede instalar temporalmente un controlador de errores, que recopila los errores. Aquí hay un pequeño fragmento de código, que he utilizado para ese propósito:

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:

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

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

En general, puedes usar un bloque Try-Catch para lidiar con 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, puede prefijar la llamada con un signo @ como tal.

 @mysql_query($query);

Con las consultas, sin embargo, generalmente es una buena idea hacer algo como esto para tener 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 />');

Debería usar el manejo de errores en los casos en que no tenga un 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 de los más comunes son después de las llamadas a funciones que devuelven un valor, o cuando tratan con los resultados de una consulta de base de datos. Nunca debe asumir que la devolución de una función será lo que usted espera, y debe asegurarse de codificar con anticipación. No tienes que usar los bloques try / catch, aunque son útiles. Muchas veces usted puede arreglárselas con una simple verificación de / else.

El manejo de errores va de la mano de las prácticas de codificación seguras, ya que hay muchos errores de " " " Eso no hace que tu script simplemente se bloquee. Si bien no se trata estrictamente de la gestión de errores, los bytes añadidos tienen una buena serie de 4 artículos sobre algunos de los conceptos básicos de la programación segura de PHP que puede encontrar AQUÍ . Hay muchas otras preguntas aquí sobre stackoverflow sobre temas como mysql_real_escape_string y Expresiones regulares que puede ser muy poderoso para confirmar el contenido de datos ingresados ??por el usuario.

La mejor práctica IMHO es utilizar el siguiente enfoque: 1. crear un controlador de errores / excepciones 2. iniciarlo en el inicio de la aplicación 3. maneja todos tus errores desde adentro

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

}

Debug :: setAsErrorHandler ();

? >

En lugar de enviar el archivo mysql_error, puede almacenarlo en un registro. de esa manera, puede hacer un seguimiento del error (y no depende de que los usuarios lo reporten) y puede ir y eliminar el problema.

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

Además de manejar los errores de inmediato en su código, también 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 especialmente útil configurar tu propio controlador de excepciones. Cuando se produce una excepción, puede realizar diferentes operaciones según el tipo de excepción.

ej: cuando una llamada a mysql_connet devuelve FALSE , lanzo una nueva DBConnectionException (mysql_error ()) y la manejo como " special " manera: registre el error, la información de conexión de la base de datos (host, nombre de usuario, contraseña), etc. e incluso envíe un correo electrónico al equipo de desarrollo para notificarles que algo puede estar realmente mal con la base de datos

Uso esto para complementar el manejo de errores estándar. Yo no recomendaría el uso excesivo de este enfoque

La supresión de errores con @ es muy lenta.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top