Проверьте тип и размер файла изображения перед загрузкой файла в php

У меня есть следующий код:

$filecheck = basename($_FILES['imagefile']['name']); $ext = substr($filecheck, strrpos($filecheck, '.') + 1); if (($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") && ($_FILES["imagefile"]["size"] < 2120000)){ } else { echo "F2"; die(); } 

Что мне нужно сделать, это проверить, является ли загруженный файл jpg / gif / png и размером менее 2 мегабайт.

Если его более 2 мегабайт или не правильный тип файла, мне нужно вернуть / echo F2 (код ошибки для api).

Когда я использую приведенный выше код для обработки файла jpg 70k, он возвращает F2.

SUBNOTE картинка im uploading имеет расширение .JPG. Может ли быть фактором? Если да, то как я могу это принять?

Обратите внимание, что вы можете не захотеть полагаться на расширения файлов, чтобы определить тип файла. Было бы довольно легко для кого-то загрузить исполняемый файл с расширением .png например. Мимический тип также может быть легко подделан вредоносным клиентом для передачи в качестве изображения. Опора на эту информацию представляет собой угрозу безопасности .

Документация по PHP :
Тип mime файла, если браузер предоставил эту информацию. Примером может служить «image / gif». Этот тип mime, однако, не проверяется на стороне PHP и поэтому не принимает его значение как должное .

Попробуйте загрузить изображения с помощью gd ( getimagesize() ), чтобы убедиться, что они фактически являются действительными изображениями (а не просто случайными файлами, притворяемыми заголовком файла изображения … finfo_file зависит от этих заголовков).

 if($_FILES["imagefile"]["size"] >= 2120000) { echo "F2"; die(); } else { $imageData = @getimagesize($_FILES["imagefile"]["tmp_name"]); if($imageData === FALSE || !($imageData[2] == IMAGETYPE_GIF || $imageData[2] == IMAGETYPE_JPEG || $imageData[2] == IMAGETYPE_PNG)) { echo "F2"; die(); } } 

Если вы действительно должны использовать расширение, чтобы проверить, является ли файл изображением, используйте strtolower() чтобы добавить расширение в нижний регистр.

 $filecheck = basename($_FILES['imagefile']['name']); $ext = strtolower(substr($filecheck, strrpos($filecheck, '.') + 1)); if (!(($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") && ($_FILES["imagefile"]["size"] < 2120000))){ echo "F2"; die(); } 

SUBNOTE картинка im uploading имеет расширение .JPG. Может ли быть фактором? Если да, то как я могу это принять?

Да, это проблема. Вы должны добавить strtolower () в эту строку:

 $ext = substr($filecheck, strrpos($filecheck, '.') + 1); 

как:

$ ext = strtolower (substr ($ filecheck, strrpos ($ filecheck, '.') + 1));

Это исправит вашу текущую проблему. Но технически вы не должны беспокоиться о расширениях файлов, вам действительно нужно только проверить тип MIME

Сравнения, такие как $ext == "jpg" проверяют только то, что $ext является точно "jpg".

Вы можете использовать strtolower на $ ext перед выполнением этих сравнений, чтобы справиться с ситуацией «.JPG».

Если вы используете PHP <= 5.2, вы можете использовать mime_content_type для проверки типа содержимого файлов вместо того, чтобы полагаться на $_FILES['imagefile']['name'] и / или $_FILES["imagefile"]["type"] , которые оба отправляются клиентом, и могут, как таковые, подделываться.

Если вы используете PHP> = 5.3, вам может finfo_file новое расширение fileinfo , и это функция finfo_file

Для размера файла вы уже используете $_FILES["imagefile"]["size"] ; это нормально, я думаю, но вы будете знать об этом только тогда, когда файл был загружен. Тем не менее, я не вижу реального способа проверить это, прежде чем загружать, боюсь …

вы можете найти некоторый код JS для первой предварительной проверки расширения до того, как файл будет загружен, но вам все равно придется проверять серверную сторону, поскольку все, что делается на стороне клиента, по своей сути небезопасно.

Не уверен, что вы можете сделать то же самое о размере файла, хотя …

Некоторые браузеры могут поддерживать скрытое поле MAX_FILE_SIZE (см. Документацию о загрузке файла ); но не уверен, что он действительно поддерживается (никогда не видел, чтобы он использовался, на самом деле, вероятно, это не так :-()

В качестве побочного элемента вы, вероятно, захотите настроить upload_max_filesize , чтобы он мог загружать как минимум столько, сколько хотите (по умолчанию он обычно равен 2 МБ, поэтому для вас это должно быть хорошо)

Размер файла довольно очевиден, но то, что люди делают выше, чтобы проверить, что это правильный формат, несколько неэффективен и «небезопасен».

Вот что я делаю:

 if($_FILES["userPicture"]["error"] == 0) { // File was uploaded ok, so it's ok to proceed with the filetype check. $uploaded_type = exif_imagetype($_FILES["userPicture"]["tmp_name"]); // What we have now is a number representing our file type. switch($uploaded_type) { case "1": $uploaded_type = "gif"; break; case "2": $uploaded_type = "jpg"; break; case "3": $uploaded_type = "png"; break; } } 

Дополнительная информация;
http://www.php.net/manual/en/function.exif-imagetype.php

Изменить: у этого есть преимущество в работе «в каждом браузере», потому что он не полагается на имя файла или что-либо предоставленное пользователем, кроме значения массива «ошибка», которое говорит нам, что на самом деле не было ошибки.

обратите внимание, что для Internet Explorer они передают тип mime файла JPEG как image / pjpeg – который отличается от других браузеров.

Вот простая функция для получения типа mime в отношении расширения файла:

 function mime2ext($mime){ // mime is like image/jpeg $m = explode('/',$mime); $mime = $m[count($m)-1]; // get the second part of the mime type switch($mime){ case 'jpg': case 'jpeg': case 'pjpeg': return 'jpg'; break; case 'png': return 'png'; break; case 'gif': return 'gif'; break; } return ''; } 

Php – это язык сценариев на стороне сервера, и если изображения находятся на стороне клиента, вы не можете проверить их размер через php перед загрузкой.

Вам нужны две вещи:

Сделайте свой регистр проверки на отсутствие расширения:

 if($strtolower($ext == "jpg")){ // do your stuff } 

Проверьте, действительно ли файл содержит изображение. Легкий способ сделать это – fileinfo:

 $finfo = finfo_open(FILEINFO_MIME_TYPE); echo finfo_file($finfo, $filename); $finfo_close($finfo); 

Альтернативный способ проверить, действительно ли файл является образом изображения, загружается в библиотеку изображений, такую ​​как gd. Если ваш файл можно успешно загрузить, это изображение.

Имейте в виду, что jpeg-изображения могут иметь расширение .jpg или .jpeg .