How to check the mime_type of a file after extracting with Ziparchive?

Asked

Viewed 150 times

0

With Ziparchive how can I check the mime_type of the files being unzipped?

Example, taking the elements of a compressed file https://php.net/manual/en/ziparchive.extractto.php

$path = 'zipfile.zip'

$zip = new ZipArchive;
if ($zip->open($path) === true) {

for($i = 0; $i < $zip->numFiles; $i++) {

    $zip->extractTo('path/to/extraction/', array($zip->getNameIndex($i)));


}

$zip->close();

}

1 answer

0

From php5.3+ you can use finfo, in older versions use mime_content_type (although it is rare to use older than PHP5.3), a retrocompatible function would be so:

function mimeType($file)
{
    $mimetype = false;

    if (class_exists('finfo')) {//PHP5.3+
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimetype = finfo_file($finfo, $file);
        finfo_close($finfo);
    } else if (function_exists('mime_content_type')) {//php5.3 ou inferiror
        $mimetype = mime_content_type($file);
    }

    return $mimetype;
}

Check mime-type after ripping

$path = 'zipfile.zip';
$extrairPara = 'path/to/extraction/';

$zip = new ZipArchive;

if ($zip->open($path) === true) {

    for($i = 0; $i < $zip->numFiles; $i++) {
        $nome = $zip->getNameIndex($i);
        $zip->extractTo($extrairPara, array( $nome ));

        $mime = mimeType($extrairPara . $nome); //Verifica o mime depois de extrair

        var_dump(array( $nome => $mime )); //Exibe o MIME
    }

    $zip->close();

}

Check mime-type before extracting

To check before extracting it will be necessary to use the ZipArchive::getStream, with this you can read only part of a specific file and use combined with finfo_buffer (only php5.3+), the function could be so:

function mimeTypeByResource($handle)
{
    $data = fread($handle, 5000); //Lê somente parte do handle

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimetype = finfo_buffer($finfo, $data);
    finfo_close($finfo);

    $handle = $data = null;

    return $mimetype;
}

So suppose you want to filter which types are allowed

$path = 'zipfile.zip';
$extrairPara = 'path/to/extraction/';

$zip = new ZipArchive;

if ($zip->open($path) === true) {

    for($i = 0; $i < $zip->numFiles; $i++) {
        $nome = $zip->getNameIndex($i);

        $mime = mimeTypeByResource($zip->getStream($nome)); //Verifica o mime depois de extrair

        //Extrai somente JPEG
        if ($mime === 'image/jpeg') {
             $zip->extractTo($extrairPara, array( $nome ));
        }
    }

    $zip->close();

}

You can then adapt to use with in_array, add before the for this:

//Tipos permitidos
$permitidos = array( 'image/jpeg', 'image/png', 'application/pdf' );

And then change inside the for for:

$mime = mimeTypeByResource($zip->getStream($nome)); //Verifica o mime depois de extrair

//Extrai somente os tipos permitos
if (in_array($mime, $permitidos)) {
     $zip->extractTo($extrairPara, array( $nome ));
}

Enabling fileinfo/finfo in php.ini

If finfo is not enabled you will get the following error message:

Call to Undefined Function finfo_open()

Then to enable the functions finfo_* it is necessary to edit the php.ini from your server, if it’s Windows Server (or Windows if it’s local) search on php.ini the following line:

 ;extension=php_fileinfo.dll

If it’s Linux or Mac look like this:

 ;extension=fileinfo.so

If PHP7.2 (in 7.1 and 7.0 is not so) is Linux, Mac or Windows:

 ;extension=fileinfo

then remove the ; from the front, save the edit and reboot your HTTP server such as Apache, Nginx or IIS

Browser other questions tagged

You are not signed in. Login or sign up in order to post.