If a file is uploaded to the server, is there a way using PHP, to make sure that it\'s actually a picture and not just a file with a .jpg or .gif extension?
best way to check if file is an image
function is_image($path)
{
$a = getimagesize($path);
$image_type = $a[2];
if(in_array($image_type , array(IMAGETYPE_GIF , IMAGETYPE_JPEG ,IMAGETYPE_PNG , IMAGETYPE_BMP)))
{
return true;
}
return false;
}
more: http://www.binarytides.com/php-check-if-file-is-an-image/
The most efficient way would be to look at the beginning bytes of the file and test for 'magic number' file specifier. Here is a list of magic numbers.
For the record: Now in 2013+ we can:
For max. compatibility (If you don't have GD library).
Use the always available mime-content-type ((PHP 4 >= 4.3.0, PHP 5))
$type = mime_content_type($filename);
if (strstr($type, 'image/'))
{
echo 'is image';
}
Using (part) of the GD library.
PHP: GD - Manual
array getimagesize ( string $filename [, array &$imageinfo ] )
The first element of the array will be 0 if there is no image. PHP: getimagesize
If you don't have GD installed (most of the time you will), you can read the file header as Shane mentioned.
EDIT: Actually, as Neal pointed out in the comments, the GD library is not even required to use this function. So use it.
Header check is not enough for checking the validity of an image file.
PHP Documentation clearly expresses that you shouldn't use getimagesize
to check that a given file is a valid image. See https://www.php.net/manual/en/function.getimagesize.php
I use the following function to validate a image file:
/**
* Returns TRUE if $path is a valid Image File
*
* @param string $path
* @return bool
*/
public static function isImage(string $path)
{
if (!is_readable($path)) {
return false;
}
// see https://www.php.net/manual/en/function.exif-imagetype.php for Constants
// adjust this array to your needs
$supported = [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG];
$type = exif_imagetype($path);
// $type can be valid, but not "supported"
if (!in_array($type, $supported)) {
return false;
}
// check the image content, header check is not enough
$image = false;
switch ($type) {
case IMAGETYPE_GIF:
$image = @imagecreatefromgif($path);
break;
case IMAGETYPE_PNG:
$image = @imagecreatefrompng($path);
break;
case IMAGETYPE_JPEG:
$image = @imagecreatefromjpeg($path);
break;
}
return (!!$image);
}