4

i want to know from the syntax if a url is a picture or not. example: http://www.blah.com/plo52.jpg or png or gif will return true. if the url is ending with other extension, the function will return false.

Thanks

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
CodeOverload
  • 47,274
  • 54
  • 131
  • 219

8 Answers8

14

Check for the mime-type of the file.

kjagiello
  • 8,269
  • 2
  • 31
  • 47
8

This won't tell you if it's really an image. This will only tell you what it appears to be according to the url:

$url = "http://somedomain.com/images/kittens.jpg";
if(preg_match("/\.(png|jpeg|jpg|gif|bmp)$/i", $url)) {
  print "Appears to be an image";
} else {
  print "Not an image.";
}

Outputs:

    Appears to be an image

Note that if you expect to see images fed through .php scripts or .aspx scripts, this method will fail. To have a truly-reliable test, you'll need to check the mime-type.

Sampson
  • 265,109
  • 74
  • 539
  • 565
  • 1
    +1, sometimes you have to implement something simple and effective, checking mime types might be great, but its overkill imo.... – JL. Jan 13 '10 at 20:26
  • Many image hosting sites serve an HTML page for URLs ending in image file extensions – Ben James Jan 13 '10 at 20:30
  • `if(preg_match('/\.(png|jpg|gif|bmp)$/i', $url))` should do it, as `preg_match` returns `0` (`False`) if it doesn't match and `1` else (no need to examine `$matches`). You forgot quotations marks around the expression and I would put `\.` at the beginning so that it does not match e.g. `foo.apng`. +1 – Felix Kling Jan 13 '10 at 20:31
5

I suggest making a HTTP HEAD Request so you won't need to download the entire image, and then based on the string returned parse and make sure the Content-Type is an image/jpeg, image/pjpeg, image/gif, image/png or similar image Content-Types.

<?php

function parseImage( $url ) {
        $ch = curl_init();

    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 20 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

    curl_setopt( $ch, CURLOPT_HEADER, true );
    curl_setopt( $ch, CURLOPT_NOBODY, true );

    $content = curl_exec( $ch );

    var_dump($content);
    curl_close($ch);
}

parseImage('http://sstatic.net/so/img/logo.png');

Returns

string 'HTTP/1.1 200 OK

Cache-Control: max-age=604800

Content-Length: 3438

Content-Type: image/png

Last-Modified: Sun, 10 Jan 2010 09:14:52 GMT

Accept-Ranges: bytes

ETag: "32741b5ed591ca1:0"

Server: Microsoft-IIS/7.5

Date: Wed, 13 Jan 2010 20:37:47 GMT

' (length=256)

The Content-Type header can be spoofed, sure.. but 99% of the time it won't be, which is why this method is reliable.

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
3

Non-image URLs could still stream back images. For example, an ashx or asp URL could return you image data. The best way is to check the MIME type, Response.ContentType.

Matthew Cole
  • 1,329
  • 2
  • 18
  • 30
2

If you really need to be 100% sure, you need to download the resource and check it using getimagesize().

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
1

I upvoted the preg solution, but if you really, REALLY want to know then download the file and interrogate using system functions (e.g. for linux use file via exec).

Mike
  • 2,523
  • 1
  • 18
  • 9
1

You can use pathinfo for getting the extension:

echo pathinfo('http://www.blah.com/plo52.jpg', PATHINFO_EXTENSION); // jpg

then wrap it into a function

function hasExtension($uri, array $extensions = array('jpg','gif','png'))
{
    return in_array(pathinfo($uri, PATHINFO_EXTENSION), $extensions);
}

hasExtension('http://www.blah.com/plo52.jpg'); // true

This will also work on regular file paths and by being able to pass the $extension array you are not limited to the regex pattern. Note the function is case sensitive though.

See this question and answers for how to best determine the MimeType of a file:

Community
  • 1
  • 1
Gordon
  • 312,688
  • 75
  • 539
  • 559
1

Use headers_list and then check the Content-Type http://php.net/manual/en/function.headers-list.php

easement
  • 6,119
  • 3
  • 29
  • 36
  • You probably mean `get_headers()`. `header_list` returns the headers that have been **sent** from your server – Gordon Jan 13 '10 at 21:36