Frage an php – MIME-Typ von gezippten Dateien abrufen

3

Es ist ganz einfach, den MIME-Typ einer hochgeladenen Datei zu ermitteln:

<code>echo mime_content_type($fileatt['tmp_name']);
</code>

Ich möchte jedoch auch den MIME-Typ der Dateien überprüfen, die in einer komprimierten Datei enthalten sind. Nach dem Entpacken meiner Dateien (Durchlaufen der Dateien in der Zip und woi ist die aktuelle Datei), habe ich versucht:

<code>$info = pathinfo($zip->getNameIndex($i));
echo mime_content_type($info['dirname'] . "\\" . $info['basename']);
</code>

was den Fehler ergibt: Warnung: mime_content_type () [function.mime-content-type]: Datei oder Pfad nicht gefunden '. \ foo.pdf' inC:\Users\<user>\<website>\validation.php in Zeile 56

Mir wurde klar, dass diedirname Bei einer komprimierten Datei handelt es sich um eine relative Datei zur komprimierten Datei, nicht um den absoluten Pfad. Deshalb habe ich Folgendes versucht:

<code>$a = pathinfo($fileatt['tmp_name']);
$b = $a['dirname'] . "\\" . $info['basename'];
echo mime_content_type($b);
</code>

was den Fehler ergibt: Warnung: mime_content_type () [function.mime-content-type]: Datei oder Pfad nicht gefunden 'C: \ xampp \ tmp \ foo.pdf' inC:\Users\<user>\<website>\validation.php in Zeile 56

Kann jemand den Pfad der Datei beleuchten? (Ich vermute, die Antwort ist die gleiche wie der Kommentar zuAbrufen der Bildhöhe und -breite aus komprimierten Dateien, aber gibt es alternative Methoden?)

AKTUALISIEREN

Dank Baba funktioniert Folgendes:

<code>$fp = fopen('zip://C:\Users\<user>\<website>\test.zip#foo.jpg', "r");
</code>

(n.b. Ich kann dies nur zum Laufen bringen, wenn ich die vollständige Route der Zip-Datei angabe, nicht eine tmp-Datei, wie dies der Fall wäre, wenn eine Datei über ein Formular hochgeladen wird). Versuchen Sie jedoch, den MIME-Typ zu ermitteln:echo mime_content_type($fp); generiert den Fehler:

<code>Warning: mime_content_type() [function.mime-content-type]: stream does not support seeking in C:\Users\<user>\<website>\includes\validation.php on line 70
</code>

Dies geschieht unabhängig vom Dateityp (d. H. Dem im einzigen Kommentar zu angegebenen Problem)http://php.net/manual/en/ziparchive.getstream.php scheint mich nicht zu beeinflussen).

Dies ist übrigens auch der gleiche Fehler, den ich erhalte, wenn ich eine andere Methode ausprobiere:$fp = $zip->getStream('foo.jpg');

Ich weiß, dass es mehrere andere "Stream nicht unterstützte" Fragen zu SO gibt, aber ich konnte nicht herausfinden, wie sie mit meinem Problem zusammenhängen, und ich hatte gehofft, dass jemand eine gute Antwort haben könnte, da diese Methode speziell vorgeschlagen wurde. .

Ich benutze das nichtfinfo_* funktioniert, da mein Host sich derzeit weigert, PHP v5.3 zu installieren.

Sie können nur verwendenmime_content_type() Bei physischen Dateien bedeutet dies, dass Sie Dateien aus Ihrer ZIP-Datei in ein Verzeichnis extrahieren und sie dann durchlaufen müssen, und nicht nur die Dateiliste außerhalb der ZIP-Datei durchlaufen müssen. Nadh
Hast du es mit dem getestet?Zip extension's stream wrapper ? Baba

Deine Antwort

2   die antwort
2

Ich weiß, dass Sie erwähnt haben, dass Sie keine Antwort für php <5.3 gefunden haben, aber ich war ein bisschen festgefahren und habe es nur herausgefunden, hoffentlich wird es denjenigen in der neuesten Version von Nutzen sein - ich konnte es nicht sehen anderswo geschrieben.

Ganz einfach, können Sie verwendenfinfo-> buffer Klicken Sie auf die Binärdaten, um den MIME-Typ zu extrahieren, der verfügbar ist, ohne den Inhalt in eine neue Datei zu extrahieren.

<code>$zip = new ZipArchive;
$zip->open("dir/archive.zip");
$binary = $zip->getFromIndex($fileToUnzip);
$filename = $zip->getNameIndex($fileToUnzip);
$zip->close();

$finfo = new finfo(FILEINFO_MIME_TYPE);
$MIMETypeandCharset = $finfo->buffer($binary);

// discard charset info
$MIMETypeAndCharsetArray = explode(';', $MIMETypeAndCharset);
$MIMEtype = $MIMETypeAndCharsetArray[0];


// you can change the source of an iframe to this php file in order to view a preview
// If the browser can't handle the file, the user is presented with a download box

header('Content-Type:$MIMEtype');
header('Content-Disposition: inline; filename="July Report.pdf"')
echo $binary;
</code>
2

A. Sie können anfangen, indem Sie versuchen

<code> mime_content_type('zip:///path/to/file.zip#'. $chapterZip->getNameIndex ( $i ));
</code>

B. Woran ich jetzt nur denken kann, ist ein Ersatz fürmime_content_type Es ist vielleicht nicht der beste Ansatz, aber ich bin sicher, er würde auftauchen, bis ich eine bessere Lösung finde

<code>$chapterZip = new ZipArchive ();
if ($chapterZip->open ( "stockoverflow.zip" )) {
    for($i = 0; $i < $chapterZip->numFiles; $i ++) {
        var_dump ( mime_content_type_replacement ( $chapterZip->getNameIndex ( $i ) ) );
    }
}
</code>

Ersatzfunktion mitfile extension undfinfo_open ( FILEINFO_MIME )

<code>function mime_content_type_replacement($filename) {

    $mime_types = array (

            'txt' => 'text/plain',
            'htm' => 'text/html',
            'html' => 'text/html',
            'php' => 'text/html',
            'css' => 'text/css',
            'js' => 'application/javascript',
            'json' => 'application/json',
            'xml' => 'application/xml',
            'swf' => 'application/x-shockwave-flash',
            'flv' => 'video/x-flv',

            // images
            'png' => 'image/png',
            'jpe' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'jpg' => 'image/jpeg',
            'gif' => 'image/gif',
            'bmp' => 'image/bmp',
            'ico' => 'image/vnd.microsoft.icon',
            'tiff' => 'image/tiff',
            'tif' => 'image/tiff',
            'svg' => 'image/svg+xml',
            'svgz' => 'image/svg+xml',

            // archives
            'zip' => 'application/zip',
            'rar' => 'application/x-rar-compressed',
            'exe' => 'application/x-msdownload',
            'msi' => 'application/x-msdownload',
            'cab' => 'application/vnd.ms-cab-compressed',

            // audio/video
            'mp3' => 'audio/mpeg',
            'qt' => 'video/quicktime',
            'mov' => 'video/quicktime',

            // adobe
            'pdf' => 'application/pdf',
            'psd' => 'image/vnd.adobe.photoshop',
            'ai' => 'application/postscript',
            'eps' => 'application/postscript',
            'ps' => 'application/postscript',

            // ms office
            'doc' => 'application/msword',
            'rtf' => 'application/rtf',
            'xls' => 'application/vnd.ms-excel',
            'ppt' => 'application/vnd.ms-powerpoint',

            // open office
            'odt' => 'application/vnd.oasis.opendocument.text',
            'ods' => 'application/vnd.oasis.opendocument.spreadsheet' 
    );

    $ext = pathinfo ( $filename, PATHINFO_EXTENSION );
    if (array_key_exists ( $ext, $mime_types )) {
        return $mime_types [$ext];
    } elseif (function_exists ( 'finfo_open' )) {
        $finfo = finfo_open ( FILEINFO_MIME );
        $mimetype = finfo_file ( $finfo, $filename );
        finfo_close ( $finfo );
        return $mimetype;
    } else {
        return 'application/octet-stream';
    }
}
</code>

Für mehr Pantomimetypen

PHP / Mime Types - Liste der öffentlich verfügbaren Mime Types?

http://snipplr.com/view/1937/

Bearbeiten 1

Habe gerade folgendes getestet und es funktioniert

<code>$fp = fopen('zip://C:\stockoverflow.zip#1.MOV.xml',"r");
</code>

Bearbeiten 2

EIN.mime_content_type($fp) würde da nicht funktionierenmime_content_type nur String-Argumente akzeptieren siehehttp://php.net/manual/en/function.mime-content-type.php

B. Bin mir nicht sicher, warum du immer noch dabei bistmime_content_type weil es auch abgeschrieben wurde

Diese Funktion ist veraltet, da die PECL-Erweiterung Fileinfo dieselbe Funktionalität (und mehr) auf eine viel sauberere Art und Weise bereitstellt.

C. arbeiten an$fileatt['tmp_name'] Direkt ist nicht ideal. Es ist eine temporäre Datei, die nicht manipuliert werden darf. Damit Sie an dieser Datei arbeiten können, müssen Sie sie auf den Server kopieren, auf dem Ihr PHP die volle Berechtigung für den Zugriff hat

D.ZipArchive::getStream würde nur auf einer lokalen Kopie der arbeitenzip Datei nicht temporäre Upload-Datei

Danke für den Vorschlag. Ich bin nicht sicher, was los ist: Ich habe$fp = fopen('zip:\\\\\\'.$a['dirname'].'\\test.zip#file.pdf', 'r'); (Backslashes wegen Windows, und sie müssen alle maskiert werden - ich nehme an, das ist richtig?),$a ist das gleiche wie in meiner Frage definiert; aber ich bekomme den fehler:Warning: fopen(zip:\\\C:\xampp\tmp\test.zip#file.pdf) [function.fopen]: failed to open stream: Invalid argument in C:\Users\<user>\<website>\includes\validation.php on line 60 ChrisW
Vielen Dank für Ihre hilfreichen Kommentare. Ich habe mehr Informationen in meine Frage aufgenommen - wenn Sie weitere Vorschläge haben, probiere ich sie gerne aus :) ChrisW
$fp = fopen('zip://C:\stockoverflow.zip#1.MOV.xml',"r"); funktioniert Baba
Siehe Antwort auf meine Antwort Baba
Ich denke, die allgemeine Antwort ist, dass es nicht möglich ist, das zu tun, was ich will, ohne die erste Zip zu speichern. Die PECL-Erweiterungen sind nur in PHP 5.3+ enthalten (das mein Host nicht installiert - anscheinend bringt es zu viele Dinge kaputt ...). Wenn dasfinfo_* Methoden werden abgeschrieben, was soll ich stattdessen verwenden? ChrisW

Verwandte Fragen