PHP check if file is an image
Solution 1
Native way to get the mimetype:
For PHP < 5.3 use mime_content_type()
For PHP >= 5.3 use finfo_open() or mime_content_type()
Alternatives to get the MimeType are exif_imagetype and getimagesize, but these rely on having the appropriate libs installed. In addition, they will likely just return image mimetypes, instead of the whole list given in magic.mime.
While mime_content_type
is available from PHP 4.3 and is part of the FileInfo extension (which is enabled by default since PHP 5.3, except for Windows platforms, where it must be enabled manually, for details see here).
If you don't want to bother about what is available on your system, just wrap all four functions into a proxy method that delegates the function call to whatever is available, e.g.
function getMimeType($filename)
{
$mimetype = false;
if(function_exists('finfo_open')) {
// open with FileInfo
} elseif(function_exists('getimagesize')) {
// open with GD
} elseif(function_exists('exif_imagetype')) {
// open with EXIF
} elseif(function_exists('mime_content_type')) {
$mimetype = mime_content_type($filename);
}
return $mimetype;
}
Solution 2
The getimagesize() should be the most definite way of working out whether the file is an image:
if(@is_array(getimagesize($mediapath))){
$image = true;
} else {
$image = false;
}
because this is a sample getimagesize() output:
Array (
[0] => 800
[1] => 450
[2] => 2
[3] => width="800" height="450"
[bits] => 8
[channels] => 3
[mime] => image/jpeg)
Solution 3
Using file extension and getimagesize
function to detect if uploaded file has right format is just the entry level check and it can simply bypass by uploading a file with true extension and some byte of an image header but wrong content.
for being secure and safe you may make thumbnail/resize (even with original image sizes) the uploaded picture and save this version instead the uploaded one.
Also its possible to get uploaded file content and search it for special character like <?php
to find the file is image or not.
sf89
Updated on June 29, 2020Comments
-
sf89 almost 4 years
Is there a way to make sure a received file is an image in
PHP
?Testing for the extension doesn't sound very secure to me as you could upload a
script
and change its extension to whatever you want.I've tried to use
getimagesize
too, but there might be something more suited for that particular problem. -
sf89 about 11 yearsUnfortunately, this seems to have been deprecated.
-
sf89 about 11 yearsYeah this was my gut feeling but I was looking for something that would be precisely suited to get the type of the file as you could trick this method. I've seen this done with Gifs (see here ha.ckers.org/blog/20070604/…).
-
Dead Man about 11 yearsI just updated my answer. You can try this
-
sf89 about 11 yearsIsn't that a bit heavy? I'll look into it though.
-
sf89 about 11 yearsUsing exif_imagetype seems like what I was looking for. Thanks!
-
designosis about 10 yearsSince
getimagesize
returns false on failure, this can be pared down to$image = getimagesize($mediapath) ? true : false;
-
The Alpha about 8 years
if($array = getimagesize($mediapath)) { // true and use the $array if required }
-
Phoenix almost 8 years
finfo_fopen
,getimagesize
,exif_imagetype
,mime_content_type
are not fully secure.. i took an html code and save as png image.. after this i upload to server using filereader Api in client side and in server side using functions above write. -
Farid Movsumov almost 8 yearsThanks for solution. I think putting @ before is_array is not neccessary in this case.
-
Kushal Suthar over 7 yearsIt will not work while uploading
swf
file instead of image.swf
file will returnarray
. -
Elnoor over 7 years
getimagesize()
is much slower. Better to use exif_imagetype() -
William Bing Hua almost 7 yearsPHP official docs recommend against this secure.php.net/manual/en/function.getimagesize.php
-
Kamarul Anuar almost 7 years@Phoenix so there's is any better option to check whether the file is image file or not before upload it to server directory? thanks
-
rsz almost 7 years@WilliamBingHua yeah, they do, but the warning was not there a few years back
-
MrWhite over 6 years
finfo_fopen()
should befinfo_open()
- there is nof
beforeopen
. "Whilemime_content_type
is removed from PHP5.3" - I don't think it was ever "removed". It did appear to be (temporarily) deprecated, as many comments suggest, although there is no mention of this in the docs anymore.mime_content_type()
is part of the Fileinfo extension, which is enabled by default on PHP 5.3+ (except if you are on Windows, when you have to enable it) -
jave.web almost 6 years
function fileIsImage($filepath){ return ( strpos(mime_content_type($filepath), 'image/') === 0 ); }
-
jave.web almost 6 yearsYear 2018 PHP docs:
mime_content_type (PHP 4 >= 4.3.0, PHP 5, PHP 7)
, not any mark of "deprecated" or such... -
Admin over 4 yearsCaution: Do not use
getimagesize()
to check that a given file is a valid image. -
Pavel Kenarov over 4 yearsNOT WORK ON SVG! TESTED!
-
6opko about 3 yearsDo not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead. php.net/manual/en/function.finfo-file.php
-
Faizan Anwer Ali Rupani over 2 yearsYear 2021 PHP docs
mime_content_type (PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
, still no indication of "depreciated" notice. -
ManInTheArena over 2 yearsWhether using
getimagesize
orfinfo_file
, as @Sheen mentions, additional checks are necessary. See also: stackoverflow.com/questions/690108/…, stackoverflow.com/questions/21525125/…