2

I am trying to catch the following error due to imagecreatefromjpeg function.

Corrupt JPEG data: premature end of data segment

I don't want to display this error in the output of my PHP script so I try to use ob_start and ob_get_contents but it doesn't work. The goal is to catch this error to know which images are corrupted.

Here is my code :

ob_start();
$img = imagecreatefromjpeg($imgDestinationPath);
$output = ob_get_contents();
echo "test";
ob_end_clean();

if( $output == "Corrupt JPEG data: premature end of data segment" )
{
   $this->log("The following image is corrupted : $imgDestinationPath");
}

var_dump($output);

Output :

Corrupt JPEG data: premature end of data segment string(4) "test"

Corrupted image :

Corrupted image

Any ideas as to why I am not getting imagecreatefromjpeg output in the buffer?

Buddy
  • 21
  • 2
  • Instead of `ob_start()` try to use a `try { //Try your stuff here } catch(Exception $e) { echo "do your stuff to catch it here" }` block! Does that do the trick for you? – Rizier123 Jan 07 '15 at 10:45
  • `imagecreatefromjpeg` returns `false` if it encounters any errors. Unless I'm missing something watching the output buffer seems unnecessary here. Could you not simply do `if (!$output) { $this->log("..."); }` instead? – alexpls Jan 07 '15 at 10:50
  • 1
    There's also a good example of how to catch errors while using `imagecreatefromjpeg` on the PHP documentation site here: http://php.net/manual/en/function.imagecreatefromjpeg.php – alexpls Jan 07 '15 at 10:52
  • It was my first attempt but it didn't catch either. – Buddy Jan 07 '15 at 10:52
  • Unfortunately in my case imagecreatefromjpeg doesn't return false. var_dump(imagecreatefromjpeg($img)) returns : resource(537) of type (gd). It seems that it's just a Warning. – Buddy Jan 07 '15 at 10:55
  • ob_start is meant to redirect output. But it seems like the message is not an output, but an error message. What you can try is to disable the error message using error-reporting or display-errors (http://php.net/manual/en/errorfunc.configuration.php). In that case you should handle errors yourself! As imagecreatefromjpeg does not throws an exception a try catch wont work. Use the return value like alexpls suggested – Mark Simon Jan 07 '15 at 10:59
  • The only way I know how to redirect error/warnings is in shell using "myfile.php 2> error.log" in a shell. But putting the image conversion into an exec is not a nice way ... – Mark Simon Jan 07 '15 at 11:05
  • Did you try putting an 'at' char before funcion call? i.e.: `$img = @imagecreatefromjpeg($imgDestinationPath);`... It should ask php not to output system calls errors/warnings... Don't know if this solves your problem, but you can give it a try... – MarcoS Jan 07 '15 at 11:11
  • @Rizier Those functions do not throw exceptions, `try..catch` is pointless. – deceze Jan 07 '15 at 11:13
  • @MarcoS Yes I tried but @ has no effect on this specific error, I don't know why ! – Buddy Jan 07 '15 at 14:26

3 Answers3

1

ob buffers output on the stdout stream. Error messages aren't output on stdout, they're output on the stderr stream. The stderr stream is, by default, then output to stdout, but after ob could do anything about it.

  1. You can explicitly suppress errors with @:

    $img = @imagecreatefromjpeg($imgDestinationPath);
    

    However, it's not really a sane development practice to simply silence errors.

  2. You should switch off error display on production systems. On your development platform, seeing all errors is very very useful, arguably vital. On production through you do not want any public error output whatsoever. For this, you set display_errors in your php.ini to off. Your errors will still get logged, but will not be output to stdout.

  3. To inspect the last error that happened, use error_get_last.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • I tried to suppress error with @ but for this specific error it doesn't work ! However, if the file passed not exist @ suppress the error. – Buddy Jan 07 '15 at 14:23
  • Hmm, interesting. I don't really have the time to set up a test environment to reproduce that at the moment. Apparently that error is triggered somewhere lower-level in the gd library then circumventing PHP's regular error handling; I'm not sure such a thing is actually possible or how to prevent it though. – deceze Jan 08 '15 at 07:10
0

You can use the errormessage buffer to get the last error. (see http://php.net/manual/en/reserved.variables.phperrormsg.php )

$img = @imagecreatefromjpeg($imgDestinationPath);
if( $php_errormsg == "Corrupt JPEG data: premature end of data segment" )
{
   $this->log("The following image is corrupted : $imgDestinationPath");
}
Mark Simon
  • 81
  • 5
  • I tried to suppress error with @ but for this specific error it doesn't work ! However, if the file passed not exist @ suppress the error. – Buddy Jan 07 '15 at 14:24
0

As said in comments '@' doesn't suppress this kind of error : "Corrupt JPEG data: premature end of data segment". However, it's work for other error like bad file passed to imagecreatefromjpeg.

So I produce this evil code to detect error before using imagecreatefromjpeg.

$output = exec("jpeginfo -c $imgDestinationPath");
$size = filesize($imgDestinationPath);

if( strpos($output, (string)$size) !== false )
{
   $error = "";
   $arrayTemp = explode($size, $output);
   $message = $arrayTemp[1];

   if( strpos($message, "[OK]") === false )
   {
      $error = trim($message);
   }
}
Buddy
  • 21
  • 2