Como fazer upload e download de arquivos com CodeIgniter

Como fazer upload e download de arquivos com CodeIgniter

18/04/2016 6 Por Jonathan Lamim

Nesse tutorial vou ensinar a você como realizar upload e download de arquivos usando bibliotecas nativas do Codeigniter. Utilizaremos a biblioteca File Uploading e o helper Download.

Para começarmos, faça o download e instalação do CodeIgniter em seu ambiente de desenvolvimento.

Passo 1 – Configuração

O primeiro passo em um projeto e fazer as configurações necessárias, e nesse caso vamos configurar o carregamento das bibliotecas e helpers e também as rotas.

Bibliotecas e helpers

Para configurarmos o carregamento das bibliotecas e helpers no autoload da aplicação precisamos editar o arquivo autoload.php localizado em application/config. Nesse arquivo serão adicionadas as informações das bibliotecas e helpers que devem ser carregadas.

Veja no código abaixo como ficará a configuração, onde é carregada a biblioteca upload e os helpers url, string e download.

$autoload['libraries'] = array('upload');
$autoload['helper'] = array('url','string','download');

Rotas

As rotas são nada mais do que as URLs personalizadas e amigáveis que serão utilizadas na aplicação. Elas são editadas no arquivo routes.php localizado em application/config.

Para esse exemplo serão criadas 2 rotas e a rota default_controller será alterada.

$route['default_controller'] = 'Base';
$route['upload'] = 'Base/Upload';
$route['download/(:any)/(:any)'] = 'Base/Download/$1/$2';
  • default_controller: vai receber o nome do controlador principal da aplicação – que será criado mais adiante – e se chama Base
  • upload: recebe a identificação do método que responderá quando essa rota for acessada, nesse caso o método Upload do controlador Base
  • download/(:any)/(:any): recebe a identificação do método que responderá quando essa rota for acessada, nesse caso o método Download do controlador Base

A última rota criada recebeu 2 nós (ou segmentos como é identificado na documentação do CodeIgniter) em em sua composição, identificados pelo placeholder (:any), que quer dizer que qualquer tipo de caracter pode ser usado nesse segmento da rota. Esses valores são passados para o método através de $1, $2, e assim por diante conforme a quantidade de segmentos que forem passados.

Passo 2 – Criando as views

Vamos criar 2 views para esse tutorial, uma que será a home e que conterá o formulário para upload do arquivo, e outra que trará as informações do arquivo e o link para download.

Home

Crie um arquivo chamado home.php em application/views e adicione o código abaixo. Esse código é apenas o conteúdo da view, as tags HTML básicas de uma página devem ser inseridas por você no ato da edição do arquivo.

<div>
    <?php if(isset($error)):?>
    <div><?=$error?></div>
    <?php endif; ?>

    <form action="<?=base_url('upload')?>" method="POST" enctype="multipart/form-data">
        <div>
            <label>Selecione um arquivo (zip, rar, pdf, doc, xls, jpg, png, gif)</label>
            <input type="file" name="arquivo"/>
        </div>
        <div>
            <input type="submit" value="Processar" />
        </div>
    </form>
</div>

No código acima temos uma estrutura padrão de formulário, com um input do tipo file e um botão do tipo submit, para que seja possível enviar a imagem para o servidor. Esses dados serão enviados através da rota upload que criamos anteriormente.

No início do código temos um if que verifica se ocorreu algum erro de processamento do upload, caso tenha ocorrido ele exibe a mensagem de erro.

Download

Crie um arquivo chamado download.php em application/views e adicione o código abaixo. Esse código é apenas o conteúdo da view – assim como o anterior – as tags HTML básicas de uma página devem ser inseridas por você no ato da edição do arquivo.

<div>
    <h3>Informações do arquivo</h3>
    <?php
        foreach($dadosArquivo as $key => $value):
            if($value):
    ?>
    <strong><?=$key?></strong>: <?=$value?>
    <?php
    endif;
    endforeach;
    ?>
    <hr />
    <a href="<?=base_url()?>" >Novo arquivo</a>
    <a href="<?=$urlDownload?>">Download</a>
</div>

O código acima é tão simples quanto o da home. Ele trás logo no início as informações do arquivo, que são listadas através de um loop foreach, exibindo somente os registros possuem algum valor informado. Em seguida tem 2 links, o primeiro levando de volta para a home, onde poderá ser enviado outro arquivo e o segundo para download do arquivo.

Repare que o link para download do arquivo é informado através da variável $urlDownload. O valor dessa variável é definido no método Download do controlador Base – que criaremos em seguida.

Passo 3 – Criando o controller

Para que o nosso tutorial fique funcional, precisamos criar o controlador, assim será possível testar o carregamento das views e do upload, além de ver as informações do arquivo que foi "upado" e fazer o download dele.

Crie um arquivo chamado Base.php em application/controllers e coloque o código abaixo:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Base extends CI_Controller {

    // Método construtor da classe
    function construct(){
        parent::construct();
    }

    // Método que carregará a home
    public function Index()
    {
    // carrega a view home.php
        $this->load->view('home');
    }

    // Método que processar o upload do arquivo
    public function Upload(){

        // definimos um nome aleatório para o diretório
        $folder = random_string('alpha');
        // definimos o path onde o arquivo será gravado
        $path = "./uploads/".$folder;

        // verificamos se o diretório existe
        // se não existe criamos com permissão de leitura e escrita
        if ( ! is_dir($path)) {
        mkdir($path, 0777, $recursive = true);
    }

        // definimos as configurações para o upload
        // determinamos o path para gravar o arquivo
        $configUpload['upload_path']   = $path;
        // definimos – através da extensão –
        // os tipos de arquivos suportados
        $configUpload['allowed_types'] = 'jpg|png|gif|pdf|zip|rar|doc|xls';
        // definimos que o nome do arquivo
        // será alterado para um nome criptografado
        $configUpload['encrypt_name']  = TRUE;

        // passamos as configurações para a library upload
        $this->upload->initialize($configUpload);

        // verificamos se o upload foi processado com sucesso
        if ( ! $this->upload->do_upload('arquivo'))
        {
            // em caso de erro retornamos os mesmos para uma variável
            // e enviamos para a home
            $data= array('error' => $this->upload->display_errors());
            $this->load->view('home',$data);
        }
        else
        {
            //se correu tudo bem, recuperamos os dados do arquivo
            $data['dadosArquivo'] = $this->upload->data();
            // definimos o path original do arquivo
            $arquivoPath = 'uploads/'.$folder."/".$data['dadosArquivo']['file_name'];
            // passando para o array ‘$data’
            $data['urlArquivo'] = base_url($arquivoPath);
            // definimos a URL para download
            $downloadPath = 'download/'.$folder."/".$data['dadosArquivo']['file_name'];
            // passando para o array $data
            $data['urlDownload'] = base_url($downloadPath);

            // carregamos a view com as informações e link para download
            $this->load->view('download',$data);
        }
    }

    // Método que fará o download do arquivo
    public function Download(){
        // recuperamos o terceiro segmento da url, que é o nome do arquivo
        $arquivo = $this->uri->segment(3);
        // recuperamos o segundo segmento da url, que é o diretório
        $diretorio = $this->uri->segment(2);
        // definimos original path do arquivo
        $arquivoPath = './uploads/'.$diretorio."/".$arquivo;

        // forçamos o download no browser
        // passando como parâmetro o path original do arquivo
        force_download($arquivoPath,null);
    }
}

Um detalhe importante que foi aplicado a esse código é que não passamos o caminho do arquivo no servidor para o link de download. Isso evita que usuários mal intencionados tentem acessar o diretório para obter os demais arquivos. Criamos uma URL específica, que possui o nome do arquivo e o diretório, e recuperamos essa informação no método Download, onde remontamos o path original para liberar o download através da função force_download.

Algo que pode agregar muito é a compactação de arquivos na hora do download e você pode ver como fazer no tutorial Como compactar arquivos no CodeIgniter usando a biblioteca Zip.

Você pode fazer o download do código-fonte completo no botão abaixo.

Download do código-fonte

Bons estudos!