Em várias situações necessitamos enviar ou baixar de um servidor vários arquivos de uma unica vez e arquivos zip servem muito bem a este proposito, com a vantagem de diminuir um pouco o tamanho da informação. Vamos ver a seguir como manipular um arquivo ZIP através da extensão ZIP do PHP que nos permite compactar, extrair, adicionar um arquivo a um arquivo ZIP já existente, excluir um arquivo existente e como forçar o download de um arquivo ZIP.

Vamos então a criar um arquivo ZIP:

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' , ZipArchive::CREATE )  === true){
     
    $zip->addFile(  'arquivos/lorem.txt' , 'lorem.txt' );
     
    $zip->addFile(  'arquivos/not_today.jpg' , 'pasta/not_today.jpg') ;
     
    $zip->addFromString('string.txt' , "Uma string qualquer" );
     
    $zip->close();
}

Na linha 1 criamos o objeto ZipArchive que é o objeto responsável por manipular um arquivo Zip no PHP. Lembrando que a extensão zip do PHP deve estar habilitada.

Na lina 3 abrimos o arquivo através do método open que recebe como parâmetro o caminho para o arquivo zip, lembrando que se estamos criando um arquivo esse local deve ter permissão de escrita para o usuário do apache. No segundo parâmetro é fornecido o modo de abertura, o modo ZipArchive::CREATE cria o arquivo caso ele não exista, ou carrega o conteúdo do arquivo, caso ele exista ou podemos utilizar o modo ZipArchive::OVERWRITE que remove todos os arquivos pré-existentes no zip, caso ele exista e seja incluído pelo menos um elemento. Se o método open retornar true o arquivo foi aberto com sucesso.

Na linha 5 adicionamos um arquivo de texto ao arquivo zip chamando o método addFile que recebe como primeiro parâmetro o caminho do arquivo no sistema de arquivos e como segundo parâmetro o nome que ele terá dentro do arquivo zip.

Na linha 7 adicionamos um segundo arquivo no arquivo zip como na linha 5, mas no parâmetro do nome do arquivo no zip colocamos um diretório e a seguir colocamos o nome do arquivo o que fará ser criada uma pasta dentro do arquivo zip que irá conter nosso arquivo.

Na linha 9 adicionamos mais um arquivo mas desta vez usamos o método addFromString que adiciona um arquivo não do sistema de arquivo mas de uma variável string do código PHP(bastante útil se o conteúdo do arquivo for gerado dinamicamente). Para isso o primeiro parâmetro é o nome do arquivo no zip e o segundo parâmetro será o conteúdo do arquivo.

Na linha 11 fechamos o arquivo através do método close que grava as alterações feitas no arquivo.

Descompactando Um arquivo zip

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' )  === true){
     
    $zip->extractTo('zips/extraido');
 
    $zip->extractTo('zips/', array('string.txt','lorem.txt'));
     
    $zip->close();
}

Na linha 1 e 3 tem a mesma função do exemplo anterior.

Na linha 5 extraímos o conteúdo do arquivo zip através do método extractTo que recebe como parâmetro o caminho no sistema de arquivo onde serão colocados o arquivos descompactados.

Na linha 7 também extraímos arquivos do arquivo zip mas especificamos através de um array os arquivos que queremos extrair.

Listando os arquivo dentro de um zip

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' )  === true){
     
     for ($i = 0; $i < $zip->numFiles; $i++) {
 
        echo $zip->getNameIndex($i)."<br />";
     }
}

Quando não sabemos os nomes dos arquivos de um zip podemos utilizar o seu índice para descobri-los, lembrando que o índice é dado pelo lugar que o arquivo é armazenado dentro do zip, então ao inserir um novo arquivo no zip o índice de outros arquivos já presente pode mudar.

Para listar os arquivos pelo índice é necessário acessá-los pelo método getNameIndex(linha 7) que recebe como parâmetro o próprio índice. Para saber quantos arquivos tem dentro do arquivo zip, para acessá-los em um loop por exemplo, utilizamos o método numFiles como vemos na linha 5.

Adicionamos um arquivo ao zip

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' )  === true){
     
    $zip->addFile('arquivos/adicionado.txt' , 'adicionado.txt');
 
    $zip->close();
}    

Basicamente para adicionar um arquivo a um arquivo zip existente basta abrir ele(linha 3) e adicionar o novo arquivo através do método addFile.

Deletando um arquivo de zip

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' )  === true){
     
    $zip->deleteName('adicionado.txt');
 
    $zip->deleteName('pasta/not_today.jpg');
 
    $zip->close();
}

Para deletar chamamos o método deleteName passando como parâmetro o nome do arquivo dentro do arquivo zip, inclusive o nome do diretório se o arquivo estiver dentro de um dentro do zip, como vemos na linha 7. Também podemos deletar um arquivo pelo seu índice pelo método deleteIndex($indice).

Carregando um arquivo de um arquivo zip para o php sem extrair

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' )  === true){
     
        $conteudo_txt = $zip->getFromName('string.txt');
        echo $conteudo_txt;
         
        echo "<br />==============================<br />";
         
        $conteudo_php = $zip->getFromIndex(0);
}

Podemos também carregar um arquivo direto do arquivo zip para uma uma variável do PHP sem ser necessário extrair o arquivo para o sistema de arquivo e depois lê-lo, fazemos isso através dos métodos getFromName que recebe como o nome do arquivo ou o método getFromIndex que recebe o índice do arquivo no zip.

Forçando o download de um arquivo zip

$zip = new ZipArchive();
 
if( $zip->open( 'zips/arquivo.zip' , ZipArchive::CREATE  )  === true){
     
    $zip->addFile(  'arquivos/lorem.txt' , 'lorem.txt' );
     
    $zip->addFile(  'arquivos/not_today.jpg' , 'pasta/not_today.jpg') ;
     
     
    $zip->close();
 
    header('Content-type: application/zip');
    header('Content-disposition: attachment; filename="arquivo.zip"');
    readfile('zips/arquivo.zip');
 
    unlink('zips/arquivo.zip');
}

Para forçar o download de um arquivo zip primeiro criamos uma arquivo zip (óbvio!!!) como vimos no primeiro exemplo, após isso mudamos o header para o tipo de um arquivo zip application/zip” (linha 12).

Na linha 13 forçamos o navegador a baixar o arquivo com o nome de arquivo.zip, ou senão o nome padrão para baixar o arquivo vai ser o nome do script PHP o que não seria legal!

Na linha 14 chamamos a função readfile que lê o conteúdo de um arquivo(no nosso caso o nosso zip) e exibe mandando a informação do arquivo para o navegador e ser feito o download.

Como já mandamos o arquivo zip para o usuário fazer download não precisamos mais do arquivo zip gerado então deletamos utilizando a função unlink.

Bom era isso. T++ !