Como forçar um download de um arquivo com CodeIgniter

Recentemente estava trabalhando em um projeto onde eu deveria disponibilizar arquivos para download do site. E eram arquivos de todo o tipo, deste jpgs, pdfs, docs, xls, etc.

No post de hoje nós vamos ver como forçar um download de um arquivo com CodeIgniter.

E é sabido que alguns destes arquivos abrem por padrão nos navegadores, como por exemplo imagens e pdfs, sendo necessário alguns cliques a mais pelo usuário para que ele possa salvar o arquivo em seu computador.

Mas o que eu precisava era que quando o usuário clicasse em determinado arquivo, surgisse a tela de download do navegador, independente se o navegador tivesse ou não o plugin para visualizar o arquivo.

Então, após algumas pesquisas na internet, percebi que é relativamente fácil você achar os headers  em php que forçam o download no browser.

Porém, apesar de pesquisar bastante eu não conseguia achar a solução para o problema do meu sistema. Ele tinha duas peculiaridades:

1) Os arquivos não estavam salvos em formato sanitizado, ou seja, com o nome normal mesmo. Exemplo: relatório da 2ª turma do colégio estadual de São Paulo.pdf

2) Os arquivos não estavam no mesmo servidor onde estava rodando minha aplicação, ou seja, estavam em um endereço remoto.

As soluções que eu tinha encontrado na internet só ensinavam a baixar arquivos com os nomes sanitizados, algo como: relatorio-da-2-turma-do-colego-estadual-de-sao-paulo.pdf, e que estivessem locais, pois eu precisava do caminho absoluto do arquivo.

Mesmo utilizando o file_get_contents, que lhe permite ler um arquivo de um endereço remoto, eu não conseguia fazer funcionar o download dele.

Então, após algumas modificações, eu cheguei a uma solução que me resolveu parcialmente o problema. Eu simplesmente copiava o arquivo via php do servidor remoto para uma pasta local no meu servidor, depois chamava a função que forçava o download e tudo funcionava.

Mas só funcionava para os arquivos com os nomes bonitinhos, sem acentos ou espaços em branco. Quando achava um arquivo que não estava assim, não funcionava mais.

Após várias mudanças no código, este já estava ficando enorme e não estava funcionando do jeito que eu queria, até que, tcharammm, fui dar uma pesquisada no user guide do CodeIgniter e vi que ele tinha uma função dedicada só pra download de arquivos.

A função chama-se force_download e está dentro do helper download. 

Então, simplesmente com apenas uma linha, eu consegui resolver todos os problema de download, mesmo no caso dos arquivos com o nome detonado e também para arquivos que estavam em um outro servidor. Não é uma maravilha?

Para você usar a função, primeiro carregue o helper, assim:

$this->load->helper('download');

Depois, preencha os requisitos e chame a função, assim:

$data = file_get_contents("/path/to/photo.jpg"); // Read the file's contents
$name = 'myphoto.jpg';

force_download($name, $data);

E pronto!

Eu falei no texto acima que fiz isso em uma linha. É porque dá mesmo, é só você colocar os parâmetros dentro da função, assim:

force_download("myphoto.jpg", file_get_contents("/path/to/photo.jpg"));

Agora fala a verdade, esse CodeIgniter não é demais?

Consegui substituir pelo menos umas 30 linhas de código por apenas uma, e que funciona perfeitamente.

O post de hoje foi bem curto, mas muito útil ao meu ver.

Agora, vamos conversar. Deixei sua dúvida aqui embaixo nos comentários caso tenha alguma.

Abraços

Fábio

Fábio S. Reszko

Sou Programador PHP desde 2006 e eu acredito sinceramente que programar usando um Framework PHP é a solução para os problemas de códigos desorganizados, difíceis de entender e de dar manutenção no futuro. Se você também acredita nisto, então fique à vontade em explorar meu blog.