2012-02-01 5 views
5

Nuestra error_log de apache Recientemente se llena con una línea similar a la siguiente (alrededor de 50 GB):oportunidad para la función de desempaquetado

[Wed Feb 01 16:50:15 2012] [error] [client 123.123.123.123] PHP Warning: 
unpack() [<a href='function.unpack'>function.unpack</a>]: 
Type V: not enough input, need 4, have 1 
    in /var/www/vhosts/domain.com/httpdocs/imagecreatefrombmp.php on line 52 

Línea 52 en imagecreatefrombmp.bmp es el siguiente:

$COLOR = unpack("V",substr($IMG,$P,3).$VIDE); 

Esta línea está enterrada en un bucle while.

Si vuelve a ocurrir este problema, quiero que el código salga silenciosamente del ciclo while.

El problema es que no puedo replicar el problema yo mismo, así que tengo que resolverlo a ciegas.

He ideado la siguiente pequeña solución. Serviría para el propósito? Si se produce el error "Tipo V no ingresado ...", ¿atraparía el bloque try catch y devolvería false?

try{ 
     $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);    
    }catch (Exception $e) { 
     return FALSE;   
    } 
+1

Compruebe esto http://stackoverflow.com/a/1241751/1164491 – Cheery

+0

Las advertencias y excepciones no están relacionadas. –

+0

@ Cheery: Por favor, siga adelante y vote para cerrar si encuentra un duplicado. –

Respuesta

3

No se puede coger un error de PHP o una advertencia, ya que no es una excepción.

Puede probar, después de llamar al unpack, si se produjo un error con error_get_last(), pero eso no es realmente práctico.

Otra solución es set an error handler para captar la advertencia, y luego lanzar un ErrorException para esa advertencia. Luego podrá usar try/catch y return false;.

function my_error_handler($errno = 0, $errstr = null, $errfile = null, $errline = null) { 
    // If error is suppressed with @, don't throw an exception 
    if (error_reporting() === 0) { 
     return true; // return true to continue through the others error handlers 
    } 
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 
} 
set_error_handler('my_error_handler'); 

Atención: todos tus errores, advertencias, avisos, etc. se convertirán en una excepción. Eso puede bloquear su programa si tuviera uno de esos antes.

Ahora se puede coger la excepción:

try { 
    $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);    
} catch (ErrorException $e) { 
    return false;   
} 
+0

Dentro de todas las soluciones propuestas aquí. Esta solución solucionó el problema sin problemas. ¡Gracias! – Haluk

1

No. Obtiene los mensajes de error normales, no las excepciones.
(Consulte también PHP: exceptions vs errors?)

Deberá afirmar la longitud de la cadena de entrada para evitar estas advertencias. - ¿Deberían ser realmente irrelevantes para una ejecución posterior?

if (strlen($IMG) >= $P+4)) { // message said it needs 4 bytes 
+0

¿Entonces el siguiente sería el truco? 'if (strlen ($ IMG)> = $ P + 4)) {$ COLOR = desempaquetar (" V ", substr ($ IMG, $ P, 3). $ VIDE); } else {return FALSE;} ' – Haluk

+0

Creo que sí. * Evitaría * el problema, por lo tanto, se registrará la advertencia. – mario

2

En este caso (esto no siempre es el caso de unpack, que depende del tipo) siempre establece $ COLOR a booleano falso en caso de error.

Puede comprobar que de esta manera:

$COLOR = unpack("V",substr($IMG,$P,3).$VIDE); 
if ($COLOR === FALSE) { /* error handling */ } 

Nota el uso de === en lugar de ==, se comprueba que coincide con el tipo a. Impide instancias en las que 0 == false devuelve verdadero.

+0

Esto parece una buena solución. La solución de @mario también se ve bien. – Haluk

Cuestiones relacionadas