Upload e Download de arquivos com CodeIgniter

Nesse tutorial vou ensinar a você como trabalhar com upload e download de arquivos usando libraries nativas do Codeigniter.

Para começarmos, faça o download e instalação do CodeIgniter em seu ambiente de desenvolvimento. Caso tenha dúvidas como fazer esse procedimento, veja nesse post um passo a passo.

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 libraries e helpers e também as rotas.

Libraries e helpers

Para configurarmos o carregamento das libraries 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 libraries e helpers que devem ser carregados.

Veja no código abaixo como ficará a configuração, onde é carregada a library ‘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';

  1. ‘default_controller’ vai receber o nome do controller principal da aplicação – que será criado mais adiante – e se chama Base.
  2. ‘upload’ recebe a identificação do método que responderá quando essa rota for acessada, nesse caso o método ‘Upload’ do controller Base.
  3. ‘download/(:any)/(:any)’ recebe a identificação do método que responderá quando essa rota for acessada, nesse caso o método ‘Download’ do controller Base.

A última rota criada recebeu 2 nós em em sua composição, identificados pela regex “(:any)”, que quer dizer que qualquer tipo de caracter pode ser usado nessa parte da rota. Esses valores são passados para o método através de $1, $2, e assim por diante, conforme a quantidade de nós 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 controller Base – que criaremos em seguida.

Passo 3 – Criando o controller

Para que o nosso tutorial fique funcional, precisamos criar o controller, 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’.

Você pode fazer o download do código-fonte completo e até mesmo acessar uma versão demo nos botões abaixo.

Bons estudos!

 

button-codigo-fonteDemo Online