Reputation: 48983
I am re-building my photo-uploading section on my site, I am trying to learn as much as I can so I can do it securely but also with best performance. MY site has aound 15-20 photos uploaded per minute usually
So is this method reliable for gettting the photo's file type, like jpg, gif, png?
$fileType = $_FILES['image']['type'];
Upvotes: 3
Views: 6041
Reputation: 8918
File extensions lie, or can at least. It is definitely best not to rely on/trust user submitted data. Also, as the PHP manual notes:
$_FILES['userfile']['type'] - The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted.
This is not reliable.
Here's a better way:
PHP's getimagesize()
function returns a numerically indexed array of data about the image, and index 2 is one of the IMAGETYPE_XXX constants (a full list of which is available here) indicating the type of the image. These can then be used in a number of GD family functions, the two relevant ones being image_type_to_extension()
and image_type_to_mime_type()
.
So, you could easily do something along these lines:
$imageData = getimagesize($_FILES['userfile']['tmp_name']);
// $imageData[2] will contain the value of one of the constants
$mimeType = image_type_to_mime_type($imageData[2]);
$extension = image_type_to_extension($imageData[2]);
Although, iif you have the exif
extension available, the [exif_imagetype()][5]
function will return the exact same result as index 2 of getimagesize()
but is much faster.
I've used the GD methods as my primary example, because they are more commonly present across PHP installs. But the Imagick extension also offers similar functionallity, and you could also verify the mime type with the fileinfo
extension (included since 5.3, btw).
Upvotes: 13
Reputation: 10207
First try getimagesize
or exif_imagetype()
,
if it doesn't return ['mime']
, try finfo_file
(if extension_loaded('fileinfo')
),
if still no results, try mime_content_type
(if function_exists('mime_content_type')
).
If you don't want mime type, but just file extension, use pathinfo($path, PATHINFO_EXTENSION)
.
Upvotes: 2
Reputation: 154691
exif_imagetype() is the safest, fastest and most reliable way to check if a given file is a valid image file, it also works with remote URLs.
The return value is the same value that getimagesize() returns in index 2 but exif_imagetype() is much faster.
$type = @exif_imagetype($_FILES['image']['tmp_name']);
if (($type >= 1) && ($type <= 3))
{
echo 'Valid image (GIF, JPG or PNG).';
}
else
{
unlink($_FILES['image']['tmp_name']); // delete it
}
Upvotes: 2
Reputation: 12047
As the doc says,
The mime type of the file, if the browser provided this information. [...] This mime type is however not checked on the PHP side and therefore don't take its value for granted.
In other word, you shouldn't trust it because I could upload pretty much anything I want and make it look like a jpeg to you.
To make sure an uploaded file is actually an image, I've personnaly used Imagick::identifyImage in the past with excellent results. GD probably has the same kind of function available.
Or you could get the mime type server side using the fileinfo extension, more specifically finfo_file()
Upvotes: 1