web-dev-qa-db-fra.com

Comment vérifier le type de fichier téléchargé dans PHP

J'ai utilisé ce code pour vérifier le type d'images,

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

mais certains utilisateurs se plaignent d'avoir une erreur lors du téléchargement de tout type d'images, alors que d'autres ne reçoivent aucune erreur!

Je me demandais si cela corrigeait le problème:

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

Des commentaires?

30
John

Ne jamais utiliser $_FILES..['type']. Les informations qu'il contient ne sont pas du tout vérifiées, c'est une valeur définie par l'utilisateur. Testez le type vous-même. Pour les images, exif_imagetype est généralement un bon choix:

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

Sinon, les fonctions finfo sont excellentes si votre serveur les prend en charge.

76
deceze

En plus de @deceze, vous pouvez également finfo () pour vérifier le type MIME des fichiers non-image:

$finfo = new finfo();
$fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE);
9
feeela

Bien sûr, vous pouvez vérifier si c'est une image avec exif, mais une meilleure façon, à mon avis, consiste à utiliser finfo comme ceci:

$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 );
3
Violence

C’est un script simple, à une ligne, que j’utilise souvent.

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

Fondamentalement, j'utilise mime_content_type () pour obtenir quelque chose comme "image/jpg", puis je l'explose avec "/" et je vérifie le premier élément du tableau pour voir s'il est écrit "image".

J'espère que ca fonctionne!

1
Salvi Pascual

La meilleure façon, à mon avis, est d’abord d’utiliser getimagesize () suivi de 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.");
    }

Le contrôle par getimagesize() évite certaines attaques par déni de service, car nous n'avons pas à essayer de imagecreatefromstring() dans chaque fichier fourni par l'utilisateur, qu'il s'agisse d'un fichier non-image ou d'un fichier trop volumineux. Malheureusement, selon PHP docs ne peut pas être utilisé pour vérifier le contenu de type d'image.

La imagecreatefromstring() tente enfin d'ouvrir le fichier sous forme d'image. Si cela réussit, nous avons une image.

1
Picard

Cette dernière ligne est proche. Vous pouvez utiliser: if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...

Dans le cas où je travaille actuellement, mon $_FILES..['type'] indique lui-même "text/csv", tandis que mime_content_type() et finfo() (suggéré par d'autres) indiquent "text/plain.". Comme @deceze le fait remarquer, $_FILES..['type'] n'est utile que pour savoir quel type de fichier est considéré par un client.

0
Autumn Leonard

Dans PHP 5.5, j'utilise cette fonction pour obtenir le type de fichier et vérifier si l'image:

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 

Ensuite, vous pourriez faire:

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

Liste complète des types de mime: http://www.sitepoint.com/web-foundations/mime-types-complete-list/

0
aesede