0

I'm trying to check 2 things with a string of text. First I want to check if it's a real URL. Then, if it is, I want to check if that URL is an image. I came upon this answer, and it said to do the following:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$imageURL);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

if(curl_exec($ch)!==FALSE) {
    print_r("went Throught");
}
else {
    print_r("Failed");
}

curl_close($ch);

No matter what $imageURL is, I always get Failed. How can I achieve the following:

if ($imageURL isRealUrl) {
    // Do some code
    if ($imageURL isInArrayOfImages(.png, .jpg, .GIF) {
        // Do something
    }
}
Community
  • 1
  • 1
Horay
  • 1,388
  • 2
  • 19
  • 36

2 Answers2

2

You can never be 100% sure but i would at least check for:

  1. Content Headers rather than extension (works even if the image is being served dynamically with the extension of ".php" or anything else)
  2. Check the content length header to make sure it's greater than zero and the server is not sending me a soft 404
  3. Finally check if the final image is a redirect. (incase of 404 page or a default image file)

    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    $content_length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    $content_redirect = curl_getinfo($ch, CURLINFO_REDIRECT_COUNT );
    
    $imageTypes = array('image/png','image/jpeg','image/gif');
    
    if(in_array($content_type,$imageTypes) && $content_redirect == 0 && $content_length >0){
    // is a vald image
    }
    

to stop curl from downloading the whole image file set CURLOPT_NOBODY to true.

curl_setopt($ch, CURLOPT_NOBODY, true);
Shujaat
  • 691
  • 4
  • 18
  • Hey there! Thanks for the answer! I always get "Worked but not an image" http://phpfiddle.org/main/code/c0uz-ijv9 – Horay Nov 20 '15 at 21:06
  • move `curl_close($ch);` to the very end, once you call that all info related to curl and the last request is reset. – Shujaat Nov 20 '15 at 21:13
  • Thanks for the answer! What if I want to start off with if it's false in all the if statements in the phpfiddle I sent you? I figured that I would just add '!' before every statement. I didn't get the right results when I did that. How can all the starting if statements be false and the else would be true? Meaning, the if statement would output "failed", and the else would output "Worked". – Horay Nov 20 '15 at 21:30
  • yes, you can merge both the `if` conditions into one, they are just a series of `&&` conditions. – Shujaat Nov 20 '15 at 21:43
  • I made a new phpFiddle to describe what I meant I added the '!` in the if statements. http://phpfiddle.org/lite/code/44pk-ax0p – Horay Nov 20 '15 at 21:50
  • `$httpcode < 200 || $httpcode > 300` and `! in_array($content_type, $imageTypes) || $content_redirect > 0 || $content_length ==0` – Shujaat Nov 20 '15 at 22:01
  • `&&` become `||` (so even if one of them fails we show the fail message) while all conditions are inverse now – Shujaat Nov 20 '15 at 22:02
  • When I did that, I always get "worked and is an image". I always get the else – Horay Nov 20 '15 at 22:05
  • can you send the phpfiddle link – Shujaat Nov 20 '15 at 22:06
  • http://phpfiddle.org/main/code/4gdt-8za1 Can you also fix the outer if statement please? – Horay Nov 20 '15 at 22:07
  • I didn't quite understand why it is necessary to check for URL redirect? – Horay Nov 22 '15 at 03:26
  • 1
    if the file has been deleted or moved the server might redirect you to a default image. In some cases some photo hosting sites might do it when you send too many requests or the image hosting account has exceeded a certain transfer bandwidth. But yes in certain cases it might be ok to follow a redirect, for e.g. facebook short URLs – Shujaat Nov 22 '15 at 05:37
0

Instead of using cURL, you can rely on the URL headers instead. Although this isn't 100% fool proof because some servers send incorrect headers, it's still quite relyable as it will work on most images delivered through a script. The only other way is to use getimagesize(), but this will download the entire image to your server.

Anyway, here's a script as suggested:

<?php

// URL
$url = "http://www.someurl.com/image.jpg";

// Check if URL exists
$get_headers = @get_headers($url);

if($get_headers[0] == 'HTTP/1.1 404 Not Found') {
    $url_exists = false;
} else {
    $url_exists = true;
}

// Check if URL is image using the same headers
if($url_exists){
    if(isset($get_headers['Content-Type'])){

        $type = strtolower($get_headers['Content-Type']);

        $valid_image_type = array();
        $valid_image_type['image/png']      = '';
        $valid_image_type['image/jpg']      = '';
        $valid_image_type['image/jpeg']     = '';
        $valid_image_type['image/jpe']      = '';
        $valid_image_type['image/gif']      = '';
        $valid_image_type['image/tif']      = '';
        $valid_image_type['image/tiff']     = '';
        $valid_image_type['image/svg']      = '';
        $valid_image_type['image/ico']      = '';
        $valid_image_type['image/icon']     = '';
        $valid_image_type['image/x-icon']   = '';
        $valid_image_type['image/bmp']      = '';

        if(isset($valid_image_type[$type])){
            // URL is image
        } else {
            // URL isn't an image
        }
    }
} else {
    // URL doesn't exist
}

?>
icecub
  • 8,615
  • 6
  • 41
  • 70