intente atrapar el bloque para la función de desempaquetar

Our apache error_log was recently filled up with lines similar to the following (about 50GB):

[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

Line 52 in imagecreatefrombmp.bmp is as follows:

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

This line is buried in a while loop.

If this issue happens again I want the code to quietly exit the while loop.

The problem is I cannot replicate the problem myself so I sort of need to solve it blind.

I've devised the following little solution. Would it serve the purpose? If the "Type V not input..." error occurs again would the try catch block catch it and return false?

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

preguntado el 01 de febrero de 12 a las 22:02

Warnings and exceptions are unrelated. -

@Cheery: Please go ahead and vote to close if you find a duplicate. -

@LightnessRacesinOrbit I would like to, but this privilege requires 3k -

@Cheery: Oh sorry, so it does. I wonder whether that's increased; I don't remember it being so high. -

3 Respuestas

You can't catch a PHP error or warning as it is not an exception.

You can test, after calling unpack, if an error was raised with error_get_last (), but that's not really practical.

Otra solución es establecer un controlador de errores to catch the warning, and then throw an ErrorException for that warning. You will then be able to use try/catch and 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');

Attention: all you errors, warnings, notices, etc... will be converted to an exception. That can potentially crash your program if you had one of those before.

Now you can catch the exception:

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

Respondido 02 Feb 12, 02:02

Within all the solutions proposed here. This solution fixed the problem without a glitch. Thank you! - haluk

In this instance (this isn't always the case with unpack, it depends on the type) it will always set $COLOR to boolean false on error.

You can check for that like this:

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

Tenga en cuenta el uso de === en lugar de ==, it checks that the type matches to. It prevents instances where 0 == false devuelve verdadero

Respondido 02 Feb 12, 02:02

This looks like a neat fix. @mario 's solution looks good too. - haluk

No. You are getting ordinary error messages, not exceptions.
(Ver también PHP: ¿excepciones vs errores?)

You will have to assert the input string length to avoid these warnings. - Should they really be irrelevant to further execution.

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

contestado el 23 de mayo de 17 a las 15:05

So the following would pretty much do the trick? if (strlen($IMG) >= $P+4)) { $COLOR = unpack("V",substr($IMG,$P,3).$VIDE); }else{return FALSE;} - haluk

I believe so. It would evitar the problem, thus the warning being logged. - Mario

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.