Jak sprawdzić typ przesłanego pliku w PHP

Użyłem tego kodu, aby sprawdzić rodzaj obrazów,

$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;
}

Ale niektórzy użytkownicy narzekają, że dostają błąd podczas przesyłania dowolnego rodzaju obrazów, podczas gdy inni nie dostają żadnych błędów!

Zastanawiałem się, czy to rozwiązuje problem:

if (mime_content_type($_FILES['fupload']['type']) == "image/gif"){...

Jakieś komentarze?

Author: Benyamin Jeizan, 2011-07-20

8 answers

Nigdy nie używaj $_FILES..['type']. Informacje w nim zawarte nie są w ogóle weryfikowane, są to wartości zdefiniowane przez użytkownika. Sam sprawdź typ. Do zdjęć, exif_imagetype jest zwykle dobrym wyborem:

$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
$detectedType = exif_imagetype($_FILES['fupload']['tmp_name']);
$error = !in_array($detectedType, $allowedTypes);

finfo Funkcje są świetne, jeśli twój serwer je obsługuje.

 72
Author: deceze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 23:18:07

Oprócz @deceze, możesz również finfo () sprawdzić typ MIME plików innych niż obrazy:

$finfo = new finfo();
$fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE);
 8
Author: feeela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 23:23:04

Pewnie, że możesz sprawdzić, czy jest to obrazek z exif, ale moim zdaniem lepszy sposób ma związek z finfo w taki sposób:

$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 );
 2
Author: Violence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 09:07:32

Moim zdaniem najlepszym sposobem jest najpierw użycie getimagesize () a następnie 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.");
    }

Sprawdzanie przez getimagesize() zapobiega niektórym atakom DoS, ponieważ nie musimy próbować imagecreatefromstring() Z KAŻDEGO pliku dostarczonego przez użytkownika, czy to nie-graficznego, czy zbyt dużego. Niestety, zgodnie z PHP docs nie można polegać na sprawdzaniu zawartości typu obrazu.

imagecreatefromstring() w końcu próbuje otworzyć plik jako obrazek-jeśli się powiedzie - mamy obraz.

 1
Author: Picard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-12 09:05:07

W PHP 5.5 używam tej funkcji do pobierania typu pliku i sprawdzania czy obrazek:

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 

Wtedy możesz zrobić:

if ( strpos( $filetype, 'image' ) !== false ) {
    // This is an image 
}

Pełna lista typów mime: http://www.sitepoint.com/web-foundations/mime-types-complete-list/

 0
Author: aesede,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-11 16:47:46

Jest to prosty, jednowierszowy skrypt, którego często używam.

$image = "/var/www/Core/temp/image.jpg";
$isImage = explode("/", mime_content_type())[0] == "image";

Zasadniczo używam mime_content_type (), aby uzyskać coś w rodzaju "image / jpg", a następnie eksplodować go przez " / " i sprawdzać przed pierwszym elementem tablicy, aby zobaczyć, czy jest napisane "image".

Mam nadzieję, że to zadziała!
 0
Author: Salvi Pascual,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 22:53:49

Ta ostatnia linia jest blisko. Możesz użyć: if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...

W przypadku, nad którym obecnie pracuję, mój $_FILES..['type'] zgłasza się jako "text / csv", podczas gdy zarówno mime_content_type(), jak i finfo() (sugerowane przez innych) zgłaszają " text/plain.". Jak wskazuje @deceze, $_FILES..['type'] jest przydatne tylko wtedy, gdy klient wie, jaki typ pliku jest.

 0
Author: Autumn Leonard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 19:38:14

WARNING: następująca odpowiedź nie sprawdza typu pliku. Sprawdza tylko nazwisko. Nie nadaje się do rzeczywistych celów bezpieczeństwa.

EDIT: nie używaj tej metody , ponieważ nie służy ona kontroli bezpieczeństwa. Zostawiam tę odpowiedź tutaj, aby nikt nie popełnił tego samego błędu jak ja, próbując tego.


Próbowałem następujących I to działało dla mnie:

$allowed =  array('gif','png' ,'jpg', 'pdf');
$filename = $_FILES['input_tag_name']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(!in_array($ext,$allowed) ) {
    echo 'error';
}

Link źródłowy

 -5
Author: uutsav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:24