Criando e baixando arquivos ZIP com PHP

O PHP é uma linguagem fantástica e repleta de recursos que nos surpreende todos os dias.

Não é a primeira (e não será a última) vez que me pedem para implementar um recurso para compactar arquivos de um diretório e fazer o seu download para o usuário.

Com isso resolvi escrever um post para tentar auxiliar quem esteja necessitando de implementar um recurso similar.

A estrutura do projeto de exemplo será:

  • diretorio_raiz
    • index.php
    • files
      • imagem_01.jpg
      • imagem_02.jpg
      • imagem_03.jpg
      • imagem_04.jpg

O arquivo index.php irá conter nossa lógica de programação.

O diretório files contém as imagens que iremos compactar e fazer o download.

Vamos implementar nosso arquivo index.php

Utilizarei uma classe nativa do PHP chamada ZipArchive uma poderosa classe que nos auxiliará e facilitará muito nossa manipulação de arquivos zip.

Vale observar que para usar esta classe é requerido a extensão Zip do PHP caso não esteja disponível basta executar o comando abaixo (ambiente linux) para instalar.

Com o comando acima eu instalo a extensão na versão 7.0 do PHP, caso deseja em outra versão basta substituir o número.

Antes de iniciar a codificação, nosso objetivo será:

  1. Ler os arquivos contido no diretório files.
  2. Criar o arquivo zip, contento as imagens do diretório.
  3. Baixar o arquivo zip.
  4. Remover o arquivo zip do servidor.

Após a instalação vamos iniciar nossa implementação da nossa lógica.

Primeiramente definimos nossa variáveis base;

Definimos o nome do arquivo, seu caminho e o caminho completo.

Agora necessitamos percorrer o diretório para varrer em busca de arquivos, e utilizaremos uma função nativa do PHP chamada scandir() esta função tem como responsabilidade listar arquivos e diretórios contidos do diretório que for passado.

Como podemos ver, passamos nosso path que foi declarado no início do nosso arquivo, ele irá percorrer e nos retornar um array com os nomes dos arquivos encontrados.

Como podemos ver ele retorna nos 02 primeiros incides do array os pontos de retorno do diretório, porem não iremos utilizar, então devemos remover.

Após a remoção o array ficará como o demonstrado abaixo.

Agora que dispomos dos arquivos que desejamos compactar, vamos iniciar o processo de criação do arquivo zip.

Após instanciarmos nossa classe, vamos verificar a criação do arquivo e percorrer o array que dispõem o nome dos arquivos para adiciona-los em nosso zip.

Agora se você rodar nosso arquivo index.php ele irá criar nosso arquivo zipFile.zip dentro do diretório files.

Como nossa última meta é baixar o arquivo para o usuário, vamos implementar nosso código para executar esta ação.

Agora basta executarmos novamente nosso arquivo index.php, e pronto é executado o download do nosso arquivo zip automaticamente.

Cabe uma observação, neste post eu adicionei ao arquivo zip apenas imagens jpg, porém podemos adicionar qualquer arquivo que desejarmos, png, xml, sql entre outros.

Vale lembrar também que esta é uma pequena demonstração, porém pode facilmente ser implementada e ampliada de acordo com sua necessidade 😉

Caso deseja, foi criado um repositório no GitHub  zip_php para  acessar os arquivos mencionados neste post.

Espero que tenham gostado, até a próxima pessoal

 

11 comentários sobre “Criando e baixando arquivos ZIP com PHP”

  1. Olá Diego!

    Post muito útil!

    Cara, só me tira uma dúvida que pode ser dúvida de noob.

    Qual a diferença em instanciar a classe Zip dessa forma \ZipArchive() ao invés de ZipArchive() ?

    Aqui rola dos dois jeitos.

    Valeu Cara.

    Forte abraço.

    1. Olá Mário.

      Fico feliz que tenha gostado do post.

      Faço uso do \ para especificar ao PHP que busque sua “namespace” na raiz (Classe nativa). Pois caso utilize este código juntamente com outros componentes sem o uso do \ ocorrera erro de namespace.

      Espero ter ajudado 🙂

  2. Olha eu um ano depois do Post aqui – -”

    Diego é possível eu salvar o arquivo .zip com uma data por exemplo?

    $data = date(‘d/m/Y’);
    $fileName = ‘backup-‘.$data.’.zip’;

    estou tentando desta maneira , mas não consigo! : /

    1. Resolvi! eu estava usando o formato de date com barras (‘d/m/Y’), e isso causava um conflito pois o php interpretava como diretórios, troquei por traços (‘d-m-Y’) e agora sim ta de boas!

      1. Olá Luan Alvez,

        Fora a interpretação do PHP, você não poderá criar arquivos ou diretórios com esse caractere, o sistema operacional barra pois há uma lista de caracteres especiais que não são permitidos.

        Sua solução foi bacana, pois ‘-‘ é um caracter permitido. Parabéns!

        Se me permite uma dica, sempre crie diretórios ou arquivos seguindo essas pequenas regras:
        – Não utilize acentuação.
        – Não utilize caracteres especiais, como por exemplo ‘ç’.
        – Utilize underscore como separador, por exemplo nome_do_meu_arquivo_ou_diretório.

        Essas pequenas regras irá lhe garantir que o arquivo ou diretório não terá problema em qualquer sistema operacional.

        Fico feliz que o post tenha sido útil.

        Grande abraço 🙂

    1. Olá, Flávio!

      Não compreendi com clareza sua pergunta, com isso vou tentar responder conforme compreendi.

      Descompactar utilizando PHP.
      $zip = new \ZipArchive();
      $zip->open($fullPathFile);
      $zip->extractTo($filesDestiny);
      $zip->close();
      Como observado acima, podemos utilizar a classe ZipArchive, utilizando os método open e extractTo , para que possamos abrir e remover os arquivo contidos no .zip.

      Descompactar pelo SO

      Windows.
      Clique com botão direito e selecionar a opção ‘extrair aqui’.

      Linux
      Acesse pelo terminal e digite o seguinte comando:
      unzip nome_do_arquivo.zip

      Espero ter auxiliado.

      Grande abraço e sucesso nos projetos.

  3. Bom dia Diego!
    É possível realizar alguma ação apos o ‘readfile($download) ‘ ?
    Já estou fazendo o download, mas preciso fazer algumas validações e redirecionar para uma rota especifica. Eu executo o download dentro de um Try, mas qualquer código apos o “readfile($download)” é ignorado

    Obrigado

    1. Olá, Joelson Matias.

      Sim, você pode criar um zip onde tem um diretório e dentro dele pode conter mais diretórios e/ou arquivos.

      Espero ter respondido sua dúvida.

      Obrigado por prestigiar o conteúdo.

      Abraços e sucessos em seus projetos.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *