Pergunta sobre php – Obtendo o tipo mime de arquivos compactados

3

Obter o tipo mime de um arquivo enviado é bastante fácil:

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

No entanto, eu também quero verificar o tipo mime de arquivos que estão incluídos em um arquivo compactado. Depois de descompactar meus arquivos (percorrendo os arquivos no zip e ondei é o arquivo atual), eu tentei:

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

que dá o erro: Aviso: mime_content_type () [function.mime-content-type]: Arquivo ou caminho não encontrado '. \ foo.pdf' emC:\Users\<user>\<website>\validation.php na linha 56

Percebi que odirname para um arquivo zipado é relativo ao arquivo zip, não ao caminho absoluto, então eu tentei:

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

que dá o erro: Aviso: mime_content_type () [function.mime-content-type]: Arquivo ou caminho não encontrado 'C: \ xampp \ tmp \ foo.pdf' emC:\Users\<user>\<website>\validation.php na linha 56

Alguém pode lançar alguma luz sobre o caminho do arquivo? (Eu suspeito que a resposta pode ser o mesmo que o comentário sobreObtendo a altura e a largura da imagem a partir de arquivos compactados, mas existem métodos alternativos?)

ATUALIZAR

Graças a Baba, o seguinte funciona:

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

(Eu só posso fazer isso funcionar quando eu dou a rota completa do arquivo zip, não um arquivo tmp como seria o caso quando um arquivo é carregado através de um formulário). No entanto, tentando obter o tipo mime:echo mime_content_type($fp); gera o erro:

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

Isso acontece independentemente do tipo de arquivo (ou seja, o problema declarado no único comentário sobrehttp://php.net/manual/en/ziparchive.getstream.php não parece me afetar).

Aliás, este também é o mesmo erro que recebo quando tento um método diferente:$fp = $zip->getStream('foo.jpg');

Eu sei que existem várias outras questões de 'fluxo não suportado' no SO, mas não consegui descobrir como elas se relacionavam com o meu problema, e esperava que, como esse método fosse especificamente sugerido, alguém pudesse ter uma boa resposta. .

(p.s. não estou usando ofinfo_* funciona como meu host atualmente se recusa a instalar o PHP v5.3).

Você só pode usarmime_content_type() em arquivos físicos, ou seja, você terá que extrair arquivos do seu zip para um diretório em algum lugar e, em seguida, percorrê-los, e não apenas percorrer a lista de arquivos do zip. Nadh
Você já testou com oZip extension's stream wrapper ? Baba

Sua resposta

2   a resposta
2

Eu sei que você mencionou que não encontrou uma resposta para o php <5,3, mas eu estava um pouco preso nisso e descobri, espero que seja útil para aqueles que estão na última versão - eu não consegui ver escrito em qualquer outro lugar.

Muito simplesmente, você pode usarfinfo-> buffer nos dados binários para extrair o tipo MIME, que está disponível sem extrair o conteúdo para um novo arquivo.

<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. Você pode começar tentando

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

B. O que eu só posso pensar agora é um substituto paramime_content_type pode não ser a melhor abordagem, mas tenho certeza que apareceria até eu descobrir uma solução melhor

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

Função de Substituição usandofile extension efinfo_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>

Para mais tipos de mímica

Tipos PHP / Mime - Lista de tipos mime publicamente disponíveis?

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

Editar 1

Apenas testei o seguinte e funciona

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

Editar 2

UMA.mime_content_type($fp) não funcionaria porquemime_content_type aceitar apenas argumento string verhttp://php.net/manual/en/function.mime-content-type.php

B. Não sei por que você ainda está se agarrandomime_content_type porque também foi depreciado

Esta função foi preterida como a extensão PECL Fileinfo fornece a mesma funcionalidade (e mais) de uma maneira muito mais limpa.

C. trabalhando em$fileatt['tmp_name'] diretamente não é ideal .. é um arquivo temporário e não deve ser manipulado .. para você trabalhar nesse arquivo você precisa dele para copiá-lo para o servidor onde seu PHP teria permissão para acessá-lo

D.ZipArchive::getStream só funcionaria em uma cópia local dozip arquivo de upload não temporário

obrigado por seus comentários úteis até agora; Coloquei mais algumas informações na minha pergunta - se você tiver mais alguma sugestão, terei prazer em testá-las :) ChrisW
$fp = fopen('zip://C:\stockoverflow.zip#1.MOV.xml',"r"); trabalho Baba
Eu acho que a resposta geral é que não é possível fazer o que eu quero sem salvar o zip 1st de qualquer maneira. As extensões PECL são incluídas apenas no PHP 5.3+ (que meu host não instala - aparentemente quebra muitas coisas ...). Se ofinfo_* métodos são depreciados o que devo estar usando em vez disso? ChrisW
Se responda pela minha resposta Baba
Obrigado pela sugestão. Eu não tenho certeza do que está errado: eu tenho$fp = fopen('zip:\\\\\\'.$a['dirname'].'\\test.zip#file.pdf', 'r'); (barras invertidas por causa do Windows, e todas elas precisam ser escapadas - suponho que isso esteja correto?),$a é o mesmo que definido na minha pergunta; mas eu recebo o erro: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

Perguntas relacionadas