5

Is there any way to have PHP determine whether an image file is corrupted and will not be able to display properly?

I've tried to check with fopen and check whether the URL is valid, but it hasn't worked!

Brian Webster
  • 27,545
  • 47
  • 143
  • 218
Piotr
  • 1,317
  • 4
  • 18
  • 24

6 Answers6

20

Is there any way to have PHP determine whether an image file is broken

If by broken you mean corrupted, changes are the imagecreatefrom{extension} won't be able to read them either:

if( imagecreatefromjpeg( $yourfile ) !== false ) {
    // image is okay.
}
Berry Langerak
  • 17,465
  • 2
  • 39
  • 53
  • Sometimes it is good idea, sometimes it is not. It will probably raise a warning in case of error. Warnings may be ignored by using `@`, though that would also ignore "*Fatal error: function not found*" errors, which would be difficult to debug. Also, when I used `imagecreatefromjpeg()` on a PHP file, HTTP request failed with "*The connection was reset*" message in Firefox and I got "*PHP Warning: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error*" error in Apache's (not PHP!) log, which would also be very difficult to debug. IMHO, this is bad idea. – binaryLV Jul 04 '11 at 07:13
  • @binaryLV I obviously don't mean real-time checking. You shouldn't do things like this while visitors are watching the page, but it's okay in a separate script. Also, I get the errors in my PHP error logs, so that might have been your configuration. I don't think it is a bad idea, as long as you run the script yourself, instead of using it on every page-view (which will bother the visitors). – Berry Langerak Jul 04 '11 at 07:46
  • imagecreatefromstring does this... but it does it too well unfortunately... it checks if image is corrupt... but what i am doing is displaying corrupted/glitched images... the difference being that some images are displayable although corrupted, however others cannot be displayed... i have to be able to make that distinction... so i need to tell apart a corrupted image, which is displayable and openable from one that isn't... – Piotr Jul 04 '11 at 07:48
  • @Piotr In that case, I'm afraid I'll have to disappoint you: there is no function in PHP that can mimic a browser, open the file and "look at it" as far as I know. – Berry Langerak Jul 04 '11 at 07:51
  • what about javascript... do you know if this can be done in javascript on client-side? i just need *some* way to do this... even if it's from the browser, because then i will be able to go on fine from thereon... :) – Piotr Jul 04 '11 at 07:53
  • @Piotr Javascript might be able to do it. Load the image, and try to get the dimensions of the image. If it's 0, changes are good that the image is in fact corrupted *and* not displayable. – Berry Langerak Jul 04 '11 at 08:01
  • 1
    hmmm... i can get the dimensions with PHP too, gonna try that first! :) – Piotr Jul 04 '11 at 08:05
3

If you mean broken as in a 404, and not a corrupt image, you can always use something along the lines of:

if (file_exists($imageFileName)) {
  ..
}
jerluc
  • 3,938
  • 2
  • 23
  • 44
  • Keep in mind that `file_exists()` checks both files and **directories**. I would suggest using `is_file()`. – binaryLV Jul 04 '11 at 07:02
  • okay, so imagecreatefromstring seems to get the job done... now i have a different problem - and that's because the images i'm displaying are already glitched... so i need it to shut up about the image being distorted... if it's displayed alright, then that's fine... so the warnings are in the way now. – Piotr Jul 04 '11 at 07:38
  • nevermind... found the solution. thanks very much to all who took the time to help! :) – Piotr Jul 04 '11 at 07:40
3

Javascript solution (with involving jQuery, though this should be possible to do without it too):

<script type='text/javascript'>
    $(function(){
        var files = [
            'warning-large.png',
            'warning-large-corrupted.png',
            'http://www.example.com/none.gif',
            'http://sstatic.net/stackoverflow/img/favicon.ico'
        ];
        for ( var n in files ) {
            var img = $('<img/>');
            img.error(function(){
                alert('error:\n' + this.src);
            });
            img.load(function(){
                alert('success:\n' + this.src);
            });
            img.attr('src', files[n]);
        }
    });
</script>
binaryLV
  • 8,594
  • 2
  • 36
  • 42
2

This works for me 100% :) I test if image exists by file_exists() and if it exists, you will catch corrupted images with this.

<img src="your_image_source" onerror="this.src='/path/to/backup/file'">
Jan Šafránek
  • 865
  • 9
  • 13
0

if the files are there on your server check using file_exists function in php

http://php.net/manual/en/function.file-exists.php

Sandeep Manne
  • 5,640
  • 5
  • 36
  • 51
  • Keep in mind that `file_exists()` checks both files and **directories**. I would suggest using `is_file()`. – binaryLV Jul 04 '11 at 07:04
  • hi thanks, but this doesn't work... it still sees the image as valid, ie not corrupted, and tries to display it... only it displays it with the 'broken image' icon... – Piotr Jul 04 '11 at 07:25
  • Your images are not there or its corrupted? – Sandeep Manne Jul 04 '11 at 07:27
  • if it corrupted then try to find mime type of image using mime_content_type http://php.net/manual/en/function.mime-content-type.php $tempArray = explode("/",mime_content_type(file)); if ($temp[0] == "image") { showImage } – Sandeep Manne Jul 04 '11 at 07:27
  • 2
    @Sandeep Manne, `mime_content_type()` is deprecated. Also, those generic "get mime type" functions check only few bytes of a file, something like "*if file starts with '1f8b', it might be a gzip file*", which is not enough to detect corrupted files. – binaryLV Jul 04 '11 at 08:07
0

A great way to view all your latest broken files is to use cpanel "Error Log" which will show you all the last 300 broken files.