it-swarm.com.ru

PHP Проверка загрузки файла

Я новичок PHP и в настоящее время изучаю раздел «Проверка загрузки файлов».

Я сделал страницу test.php, содержащую следующий код: 

var_dump(@$_FILES['file']['type']);

Сначала я загрузил изображение «img.gif», и оно вернулось:

string 'image/gif' (length=9)

Затем я изменил расширение изображения на «.jpg», и оно вернулось:

string 'image/jpeg' (length=10)

Поэтому я понял, что $ _FILES ["file"] ["type"] только возвращает расширение загруженного файла, но на самом деле не проверял, что это за файл. 

На этой странице http://www.w3schools.com/php/php_file_upload.asp есть код:

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

Мне интересно, почему вышеуказанные коды проверяют расширение файла дважды? Я удалил некоторые из вышеуказанных кодов, и это мой новый код:

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))

Мой код правильный? Или у вас есть более эффективные способы проверки загружаемого файла с изображением?

Спасибо!

8
nut

Вы должны передать tmp_name файла * в getimagesize , он даст вам размер и тип изображения (если это изображение). Если переданный аргумент является файлом, но не изображением, он возвращает false, что позволит вам проверить.

Правка: Единственный надежный метод проверки изображения - это сделать его копию с помощью Gd или Imagick - getimagesize можно легко взломать .

*: Я имею в виду временный файл, созданный после загрузки.

Например:

if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $file = $_FILES['file']['tmp_name'];
    if (file_exists($file))
    {
        $imagesizedata = getimagesize($file);
        if ($imagesizedata === FALSE)
        {
            //not image
        }
        else
        {
            //image
            //use $imagesizedata to get extra info
        }
    }
    else
    {
        //not file
    }
}

Этот код использует file_exists только для общих целей. Если файл не был загружен, вы получите $_FILES['file']['size'] = 0, $_FILES['file']['tmp_name'] = '' и $_FILES['file']['error'] = 4. Смотрите также is_readable . Значения ошибок приведены в объяснены ошибки загрузки файла at php.net .

15
Theraot
$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

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

В ваш измененный код можно загружать файлы другого типа с измененным расширением. как они могут загрузить документ Word с расширением .png.

Ваш новый код просто проверяет расширение и не имеет двойной проверки.

3
Maulik Vora

Ваш новый код проверяет только расширение файла и размер файла. Он не проверяет тип файла.

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

0
Yogesh Suthar