Как проверить загруженный тип файла в PHP
я использовал этот код для проверки типа изображений,
$f_type=$_FILES['fupload']['type'];
if ($f_type== "image/gif" OR $f_type== "image/png" OR $f_type== "image/jpeg" OR $f_type== "image/JPEG" OR $f_type== "image/PNG" OR $f_type== "image/GIF")
{
$error=False;
}
else
{
$error=True;
}
но некоторые пользователи жалуются, что они получают ошибку при загрузке любого типа изображений, в то время как некоторые другие не получают никаких ошибок!
мне было интересно, устраняет ли это проблему:
if (mime_content_type($_FILES['fupload']['type']) == "image/gif"){...
какие-либо замечания?
8 ответов
никогда не используйте $_FILES..['type']
. Информация, содержащаяся в нем, не проверяется вообще, это пользовательское значение. Тест тип. Для изображений,exif_imagetype
обычно хороший выбор:
$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
$detectedType = exif_imagetype($_FILES['fupload']['tmp_name']);
$error = !in_array($detectedType, $allowedTypes);
кроме того,finfo
функции отлично, если ваш сервер поддерживает их.
В дополнение к @deceze, вы можете также finfo() чтобы проверить MIME-тип файлов без изображений:
$finfo = new finfo();
$fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE);
конечно, вы можете проверить, является ли это изображение с exif, но лучший способ, я думаю, это сделать с finfo так:
$allowed_types = array ( 'application/pdf', 'image/jpeg', 'image/png' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['datei']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( 'Please upload a pdf or an image ' );
}
finfo_close( $fileInfo );
лучший способ, на мой взгляд, сначала использовать getimagesize() следовал по imagecreatefromstring().
$size = getimagesize($filename);
if ($size === false) {
throw new Exception("{$filename}: Invalid image.");
}
if ($size[0] > 2500 || $size[1] > 2500) {
throw new Exception("{$filename}: Image too large.");
}
if (!$img = @imagecreatefromstring(file_get_contents($filename))) {
throw new Exception("{$filename}: Invalid image content.");
}
проверка getimagesize()
предотвращает некоторые DoS-атаки, потому что нам не нужно пытаться imagecreatefromstring()
из каждого файла, предоставленного пользователем, либо файл без изображения или файл слишком большой. К сожалению, согласно PHP docs нельзя полагаться на проверку содержимого типа изображения.
на imagecreatefromstring()
наконец пытается открыть файл как образ-если это удается-у нас есть образ.
в PHP 5.5 я использую эту функцию для получения типа файла и проверки изображения:
function getFileType( $file ) {
return image_type_to_mime_type( exif_imagetype( $file ) );
}
// Get file type
$file_type = getFileType( 'path/to/images/test.png' );
echo $file_type;
// Prints image/png
// 1. All images have mime type starting with "image"
// 2. No other non-image mime types contain string "image" in it
затем вы могли бы сделать:
if ( strpos( $filetype, 'image' ) !== false ) {
// This is an image
}
полный список типов mime:http://www.sitepoint.com/web-foundations/mime-types-complete-list/
Это просто один сценарий, который я часто использую.
$image = "/var/www/Core/temp/image.jpg";
$isImage = explode("/", mime_content_type())[0] == "image";
в основном я использую mime_content_type (), чтобы получить что-то вроде "image/jpg", а затем взрываю его на "/" и проверяю первый элемент массива, чтобы увидеть, говорит ли он "image".
надеюсь, это сработает!
эта последняя строка близка. Вы можете использовать:
if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...
в случае, над которым я сейчас работаю, мой $_FILES..['type']
сообщает себя как "текст / csv", в то время как оба mime_content_type()
и finfo()
(предложенный другими) отчет " текст / равнина.". Как указывает @deceze,$_FILES..['type']
полезно только знать, какой тип клиент считает файл.
предупреждение: следующий ответ фактически не проверяет тип файла. Он только проверяет имя. Это не подходит для фактических целей безопасности.
EDIT: не используйте этот метод поскольку он не служит для проверки безопасности. Я оставляю этот ответ здесь, чтобы никто не сделал такую же ошибку, как я, попробовав это.
я попробовал следующее, И это сработало для меня:
$allowed = array('gif','png' ,'jpg', 'pdf');
$filename = $_FILES['input_tag_name']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(!in_array($ext,$allowed) ) {
echo 'error';
}