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

0

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

Example, getting the elements of a compressed file link

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

}
    
asked by anonymous 03.01.2018 / 19:25

1 answer

1

From php5.3+ you can use finfo , older versions use mime_content_type (if well that is rare to use older than PHP5.3), a backward compatible function would look like this:

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 the mime-type after extracting

$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 the mime-type before extracting

To check before extracting you will need to use ZipArchive::getStream , so you can read part just from a specific file and use combined with finfo_buffer (php5.3 + only), the function could look like this:

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 assuming 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 adapt later to use with in_array , add before for this:

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

And then change within for to:

$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 finfo_* functions, you need to edit the php.ini of your server, if it is Windows Server (or Windows may be local) look at php.ini the following line:

 ;extension=php_fileinfo.dll

If it's Linux or Mac look like this:

 ;extension=fileinfo.so

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

 ;extension=fileinfo

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

    
04.01.2018 / 21:08