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