How to ZIP only images from a folder with PHP?

Asked

Viewed 430 times

3

Guys, in my folder being zipped, there are files .php and images, but I need to zip only the images!

Is there any possibility with the class ZipArchive of PHP?

My job (works perfectly for everything inside 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;
    }
}

Updating: The variable $file that’s inside the foreach, does not only contain the name and extension of the file but the entire path. Example: pasta1/subpasta1/photo.jpg

  • Have you tried using pathinfo()? Follow doc: http://php.net/manual/en/function.pathinfo.php

  • $valid_files would be a filtration? o create_zip($files = array() receives "files" or "folders"?

  • $valid_files checks the valid files, ie not folder!

2 answers

4


If $files receives the files with the full path and not the folder from where you will get such files in 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 the pathinfo and the other examples in this answer, as Use finfo or pathinfo to get 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;
    }
}
  • The first did not function, brought the . php files!

  • The regex did not Zipou!

  • Open() is not supported here.

  • yeah, buddy!.....

  • First Messenger but allowed . php

  • I made an update on the question!

  • Ok, but it does not identify the file extension in the $file variable (in the first example ), as it contains folders and subfolders.

Show 3 more comments

4

Follow another alternative, is trying to use the function path_info, if the function does not exist, another means is used to recover the file extension.

The arguments the function receives are:

  1. $arquivos: Required. The array which will contain the file path.
  2. $extensoes: Required. The array which should contain valid image extensions for example: png, gif, jpg, without the ..
  3. $destino: Optional. The place of destination of zip file. The default value is Imagens.zip, to put it in another directory (level below the hierarchy) do revelacao/Imagens.zip.
  4. $sobrescrever: Optional. If set as true, will overwrite the zip file existing, the default value is false.

Example of use:

$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);
}
  • syntax error, Unexpected '[' in....($file) ['Extension'];

  • 1

    @Lollipop Sorry to intrude, just an attempt to improve the code.

  • 1

    @Guilhermenascimento Thanks for the edition!

  • I made an update on the question!

Browser other questions tagged

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