Trabalhando com arquivos ZIP com PHP
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++ !