Вопрос по php – Получение MIME-типа заархивированных файлов

3

Получить mime-тип загруженного файла достаточно просто:

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

Тем не менее, я также хочу проверить MIME-тип файлов, которые включены в ZIP-файл. После распаковки моих файлов (перебирая файлы в zip и кудаi является текущим файлом), я пытался:

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

который выдает ошибку: Предупреждение: mime_content_type () [function.mime-content-type]: файл или путь не найдены & apos;. \ foo.pdf & apos; вC:\Users\<user>\<website>\validation.php по линии 56

Я понял, чтоdirname для zip-файла это относительный zip-файл, а не абсолютный путь, поэтому я попытался:

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

который выдает ошибку: Предупреждение: mime_content_type () [function.mime-content-type]: файл или путь не найден, C: \ xampp \ tmp \ foo.pdf & apos; вC:\Users\<user>\<website>\validation.php по линии 56

Кто-нибудь может пролить свет на путь к файлу? (Я подозреваю, что ответ может быть таким же, как комментарийполучение высоты и ширины изображения из заархивированных файлов, а есть ли альтернативные методы?)

UPDATE

Благодаря Бабе, работает следующее:

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

(Нет. Я могу заставить это работать, только когда я указываю полный маршрут zip-файла, а не tmp-файла, как в случае, когда файл загружается через форму). Тем не менее, пытаясь получить MIME-тип:echo mime_content_type($fp); генерирует ошибку:

<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>

Это происходит независимо от типа файла (т.е. проблема указана в единственном комментарииhttp://php.net/manual/en/ziparchive.getstream.php не влияет на меня).

Кстати, это также та же ошибка, которую я получаю, когда пытаюсь использовать другой метод:$fp = $zip->getStream('foo.jpg');

Я знаю, что существует несколько других потоков, которые не поддерживаются. вопросы по SO, но я не могу понять, как они связаны с моей проблемой, и я надеялся, что, поскольку этот метод был специально предложен, у кого-то может быть хороший ответ ...

(п. я не используюfinfo_* работает так как мой хост в настоящее время отказывается устанавливать PHP v5.3).

Вы проверяли это сZip extension's stream wrapper ? Baba
Вы можете использовать толькоmime_content_type() что касается физических файлов, то есть вам придется извлекать файлы из zip-архива в какой-то каталог, а затем циклически перебирать их, а не просто перебирать список файлов из zip-файла. Nadh

Ваш Ответ

2   ответа
2

А. Вы можете начать с попытки

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

Б. То, о чем я могу думать только сейчас, - это заменаmime_content_type это может быть не лучший подход, но я уверен, что он появится, пока я не найду лучшее решение

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

Replacement Function using file extension and finfo_open ( FILEINFO_MIME )

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

Fore больше видов пантомимы

PHP / Mime Types - Список типов пантомимы, доступных публично?

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

Edit 1

Только что проверил следующее и все работает

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

Edit 2

A.mime_content_type($fp) не будет работать, потому чтоmime_content_type только принять строковый аргумент, см.http://php.net/manual/en/function.mime-content-type.php

Б. Не уверен, почему вы все еще придерживаетесьmime_content_type потому что это также было амортизировано

This function has been deprecated as the PECL extension Fileinfo provides the same functionality (and more) in a much cleaner way.

C. работает над$fileatt['tmp_name'] напрямую не является идеальным .. это временный файл и не подлежит манипуляциям .. для работы с этим файлом вам нужно скопировать его на сервер, где у вашего PHP будет полное разрешение на доступ к нему

D.ZipArchive::getStream будет работать только на локальной копииzip файл не временный файл загрузки

Сам ответ за мой ответ
$fp = fopen('zip://C:\stockoverflow.zip#1.MOV.xml',"r"); работает
спасибо за ваши полезные комментарии до сих пор; Я добавил больше информации в свой вопрос - если у вас есть какие-либо предложения, я буду рад их попробовать :) ChrisW
Я думаю, что в целом ответ таков, что в любом случае невозможно сделать то, что я хочу, не сохранив zip 1st. Расширения PECL включены только в PHP 5.3+ (который мой хост не установит - очевидно, он ломает слишком много вещей ...). Еслиfinfo_* методы обесцениваются, что я должен использовать вместо этого? ChrisW
Спасибо за предложение. Я не уверен, что не так: у меня есть$fp = fopen('zip:\\\\\\'.$a['dirname'].'\\test.zip#file.pdf', 'r'); (обратная косая черта из-за Windows, и все они должны быть экранированы - я полагаю, это правильно?),$a такой же, как определено в моем вопросе; но я получаю ошибку: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
2

5.3, но я немного застрял в этом и просто понял, надеюсь, он пригодится тем, кто работает в последней версии - я не смог увидеть это написано где-нибудь еще.

Проще говоря, вы можете использоватьfinfo- & GT; буфер на двоичные данные для извлечения MIME-типа, который доступен без извлечения содержимого в новый файл.

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

Похожие вопросы