webentwicklung-frage-antwort-db.com.de

Wie überprüfe ich Dateitypen von hochgeladenen Dateien in PHP?

Auf der PHP Website wird nur die Verwendung von is_uploaded_file() oder move_uploaded_file(), hier empfohlen. Natürlich Sie In der Regel möchte der Benutzer aus verschiedenen Gründen nicht, dass er irgendeine Art von Datei hochlädt.

Aus diesem Grund habe ich oft eine "strenge" MIME-Typprüfung durchgeführt. Dies ist natürlich sehr fehlerhaft, da häufig MIME-Typen falsch sind und Benutzer ihre Datei nicht hochladen können. Es ist auch sehr leicht zu fälschen und/oder zu ändern. Und dabei gehen jeder Browser und jedes Betriebssystem anders mit ihnen um.

Eine andere Methode ist die Überprüfung der Erweiterung, die natürlich noch einfacher zu ändern ist als der MIME-Typ.

Wenn Sie nur Bilder möchten, funktioniert die Verwendung von getimagesize().

Was ist mit anderen Dateitypen? PDFs, Word-Dokumente oder Excel-Dateien? Oder sogar nur Textdateien?

Edit: Wenn Sie nicht mime_content_type oder Fileinfo und system ("file -bi $ uploadedfile ") gibt den falschen Dateityp an. Welche anderen Optionen gibt es?

47
Darryl Hein

Schauen Sie sich mime_content_type oder Fileinfo an. Dies sind eingebaute PHP Befehle zur Bestimmung des Dateityps anhand des Inhalts der Datei. Überprüfen Sie auch die Kommentare auf den beiden oben genannten Seiten. Es gibt einige andere gute Vorschläge.

Persönlich hatte ich viel Glück mit etwas, das im Wesentlichen system("file -bi $uploadedfile") ist, aber ich bin nicht sicher, ob das die beste Methode ist.

33
davr

IMHO sind alle MIME-Typ-Prüfmethoden unbrauchbar.

Angenommen, Sie haben einen MIME-Typ application/pdf. Standardmethoden versuchen, etwas zu finden, das wie ein PDF Header (%PDF- Oder so ähnlich) aussieht, und sie geben 'Okay, scheint so, als wäre dies ein PDF file 'bei Erfolg. Tatsächlich bedeutet dies jedoch nichts. Sie können eine Datei hochladen, die nur %PDF-1.4 Enthält und die MIME-Prüfung besteht.

Ich meine, wenn die Datei einen erwarteten MIME-Typ hat, besteht sie immer die MIME-Typ-Prüfung, ansonsten ist das Ergebnis undefiniert.

14
Sudden Def

Ich habe mime_content_type verwendet, das mit PHP 5.2) kompatibel ist, da ich weder Fileinfo verwenden kann (es erfordert PHP 5.3) noch system(), das ist von meinem Provider deaktiviert. Zum Beispiel überprüfe ich, ob eine Datei eine Textdatei ist, also:

if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... }

Ein vollständiges Beispiel finden Sie in meinem "PHP Directory and Subdirectory Listener & File Viewer and Downloader" unter: http://www.galgani.it/software_repository/index.php

2
if(isset($_FILES['uploaded'])) {
    $temp = explode(".", $_FILES["uploaded"]["name"]);

    $allowedExts = array("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods");

    $extension = end($temp);
    if( in_array($extension, $allowedExts)) {
       //code....

    } else {
        echo "Error,not Documentum type...";
    }
}

Ich gehe davon aus, dass Sie eine feste weiße Liste von Dateitypen haben werden, die Sie akzeptieren werden.

Für jeden dieser Typen müssen Sie verschiedene Techniken anwenden, um sicherzustellen, dass sie gültige Beispiele für dieses Format sind.

Es gibt zwei verwandte Fragen:

  • Sieht es ungefähr so ​​aus, als wäre es der richtige Typ? (Bei JPEG können Sie, wie bereits erwähnt, die Header überprüfen. Bei vielen Unix-basierten Formaten können Sie das "Magic Cookie" überprüfen.)

  • Handelt es sich tatsächlich um ein gültiges Beispiel dieses Typs (z. B. können Sie für jedes XML-ähnliche Format eine Überprüfung anhand einer DTD durchführen.)

Ich denke, dass Sie für jedes Format separate Fragen stellen sollten, da die Antwort für PDFs im Vergleich zu Zip-Dateien sehr unterschiedlich ist.

2
Oddthinking

Hier ist die Funktion file_mime_type von iZend:

function file_mime_type($file, $encoding=true) {
    $mime=false;

    if (function_exists('finfo_file')) {
        $finfo = finfo_open(FILEINFO_MIME);
        $mime = finfo_file($finfo, $file);
        finfo_close($finfo);
    }
    else if (substr(PHP_OS, 0, 3) == 'WIN') {
        $mime = mime_content_type($file);
    }
    else {
        $file = escapeshellarg($file);
        $cmd = "file -iL $file";

        exec($cmd, $output, $r);

        if ($r == 0) {
            $mime = substr($output[0], strpos($output[0], ': ')+2);
        }
    }

    if (!$mime) {
        return false;
    }

    if ($encoding) {
        return $mime;
    }

    return substr($mime, 0, strpos($mime, '; '));
}
1
iZend

Für PHP> = 5.3.0 können Sie die Funktion finfo_file ( finfo_file ) von php verwenden, um die Dateiinformationen zu erhalten.

Für PHP <5.3.0 können Sie den Befehl file Ihres Systems verwenden, um die Dateiinformationen abzurufen.

Also mach es einfach in einer Funktion,

var_dump(mime_type("wiki templete.txt"));   // print string(10) "text/plain"

function mime_type($file_path)
{
    if (function_exists('finfo_open')) {
        $finfo = new finfo(FILEINFO_MIME_TYPE, null);
        $mime_type = $finfo->file($file_path);
    }
    if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {
        ob_start();
        passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);
        if ($return > 0) {
            ob_end_clean();
            $mime_type = null;
        }
        $type = trim(ob_get_clean());
        if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
            $mime_type = null;
        }
        $mime_type = $match[1];
    }
    return $mime_type;
}

MimeTypes

0
Kris Roofe