How to ZIP only images of a folder with PHP?

3

In my folder to be zipped, there are .php and images files, but I need to zip only images!

Is there a possibility with PHP's class ZipArchive ?

My function ( works perfectly for everything in the folder ):

/* creates a compressed zip file */
function create_zip($files = array(),$destination = 'revelacao/',$overwrite = false) {
    //if the zip file already exists and overwrite is false, return false
    if(file_exists($destination) && !$overwrite) { return false; }
    //vars
    $valid_files = array();
    //if files were passed in...
    if(is_array($files)) {
           //cycle through each file
           foreach($files as $file) {
               //make sure the file exists
               if(file_exists($file)) {
                   $valid_files[] = $file;
               }
            }
    }
    //if we have good files...
    if(count($valid_files)) {
           //create the archive
           $zip = new ZipArchive();
           if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
               return false;
           }

           //add the files
           foreach($valid_files as $file) {
               $new_filename = substr($file,strrpos($file,'/680') + 1);
               $zip->addFile($file,$new_filename);
           }

           //debug
           echo 'O zip contém ',$zip->numFiles,' status( 0 para ok e 1 para erro) : ',$zip->status;

           //close the zip -- done!
           $zip->close();

           //check to make sure the file exists
           return file_exists($destination);
    }
    else
    {
           return false;
    }
}
  

Update : The variable $file that is inside foreach , contains not only the file name and extension, but the entire path. Example: folder1 / subfolder1 / foto.jpg

    
asked by anonymous 26.05.2015 / 22:54

2 answers

4

If $files receives the files with the full path and not the folder where you will get those files from create_zip($files , then you can filter what is image by extension for example:

if(is_array($files)) {
    //cycle through each file
    foreach($files as $file) {
        //make sure the file exists
        if(file_exists($file) &&
           (false !== strstr($file, '.jpg') || false !== strstr($file, '.jpeg') || false !== strstr($file, '.png') || false !== strstr($file, '.gif'))
        ) {
            $valid_files[] = $file;
        }
    }
}

Or regex:

if(is_array($files)) {
    //cycle through each file
    foreach($files as $file) {
        //make sure the file exists
        if(file_exists($file) && preg_match('#\.(jpg|jpeg|gif|png)$#', $file) > 0) {
            $valid_files[] = $file;
        }
    }
}

Or using finfo_file ( finfo_* is supported from PHP5.3 ):

  

Note: This example with finfo_* is safer than pathinfo and the other examples in this answer, as Use finfo or pathinfo to get the mime type?

     

It is necessary on some servers to enable extension=php_fileinfo.dll (windows) or like-unix extension=php_fileinfo.so

function detectMimeType($file)
{
    $mime = '';
    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime  = finfo_file($finfo, $file);
        finfo_close($finfo);
    } else if (function_exists('mime_content_type')) {
        $mime = mime_content_type($file);
    }

    return $mime;
}

...

foreach($files as $file) {
    //make sure the file exists
    if(file_exists($file) && preg_match('#^image/#', detectMimeType($file)) > 0) {
        $valid_files[] = $file;
    }
}
    
26.05.2015 / 23:13
4

Here's another alternative, you're trying to use path_info function , if the function does not exist , another medium is used to retrieve the file extension.

The arguments that the function receives are:

  • $arquivos : Required . The array that will contain the path of the files.
  • $extensoes : Required . The array should contain valid extensions for image for example: png , gif , jpg , without . .
  • $destino : Optional . The location of the Zip file . The default value is Imagens.zip , to place it in a different directory ( level below the hierarchy)
  • revelacao/Imagens.zip : Optional . If set to true , it will overwrite the existing Zip file, the default value is false .
  • Example usage:

    $arquivos = glob("*.*");                 // Captura todos os arquivos do diretório atual
    $extensoes = array('gif', 'png', 'jpg'); // Extensões de imagens que você quer zipar
    
    $resultado = create_zip($arquivos, $extensoes);
    if ($resultado)
        echo "O arquivo ZIP foi criado com sucesso! \n";
    else
        echo "Não foi possível criar o arquivo ZIP. \n";
    

    Code:

    function extrairExtensao($arquivo){
        if (function_exists('pathinfo')){
            $extensao = pathinfo($arquivo, PATHINFO_EXTENSION);
            return $extensao;
        } else {
            $partes = explode('.', $arquivo);
            $extensao = end($partes);
            return $extensao;
        }
    }
    
    function create_zip($arquivos = array(), $extensoes = array(), 
                        $destino = 'Imagens.zip', $sobrescrever = false) {
        if(file_exists($destino) &&  !$sobrescrever || 
           !is_array($arquivos) || !is_array($extensoes))
             return false;
    
        $arquivosValidos = array();
    
        foreach($arquivos as $arquivo) {
            $extensao = extrairExtensao($arquivo);
            if(file_exists($arquivo) && in_array($extensao, $extensoes))
                $arquivosValidos[] = $arquivo;      
        }
    
        if (count($arquivosValidos) == 0)
            return false;
    
        $zip = new ZipArchive();
        $bandeiras = $sobrescrever ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE;
        if($zip->open($destino, $bandeiras) !== true)
            return false;
    
        foreach($arquivosValidos as $arquivoValido) {
            $arquivo = basename($arquivoValido);
            $novoArquivo = substr($arquivo, strpos($arquivo, '/680') + 1);
            if ($zip->addFile($arquivo, $novoArquivo) !== true){
                echo "O arquivo {$arquivo} não pode ser adicionado ao ZIP. \n";
                // Encerrar a função aqui?
            }
        }
    
        echo "O ZIP contém " . $zip->numFiles . " arquivos. \n";
        echo "Status( 0 para OK e 1 para ERRO): " . $zip->status . "\n"; 
        $zip->close();
        return file_exists($destino);
    }
    
        
    26.05.2015 / 23:39