sexta-feira, 12 de agosto de 2016

FORÇANDO DOWNLOAD NO PHP



Pode acontecer de você ter um site e querer disponibilizar nele o download de certos arquivos — uma música em mp3 ou uma imagem em, por exemplo — e ocorrer que, quando o usuário clicar no link desse arquivo, ao invés de o dispositivo baixá-lo, irá abri-lo, sendo que a pretensão era mesmo o de fornecer o download.

E então, o que fazer?

Simples! Vamos fazer uma função em PHP para forçar o download.

Primeiro, vamos configurar o link disponibilizado para o usuário (por exemplo, na página index.php, a qual o usuário acessa e clica para baixar o arquivo pretendido):

<a href="baixar.php">Iniciar o download</a>

Então, o usuário verá nessa página o link Iniciar o download e ao clicar sobre ele, será remetido para o arquivo baixar.php, que, no caso aqui, está no mesmo diretório.

Então, vamos escrever na página baixar.php a codificação para efetuar o download do arquivo, no nosso exemplo, um livro em PDF (iliada.pdf), que está numa pasta chamada downloads.

<?php
$arquivo = 'iliada.pdf'; // Nome do Arquivo
$local = 'downloads/'; // Pasta que contém os arquivos para download
$local_arquivo = $local.$arquivo; // Concatena diretório e arquivo

if (stripos($arquivo, './') !== false || stripos($arquivo, '../') !== false || !file_exists($local_arquivo)) {  // se há erro, do tipo, arquivo inexistente
  echo 'O comando não pode ser executado.'; // notifica o erro ao usuário
} else { // se não houver erro, prepara o arquivo para ser baixado
  header('Cache-control: private');
  header('Content-Type: application/octet-stream');
  header('Content-Length: '.filesize($local_arquivo));
  header('Content-Disposition: filename='.$arquivo);
  header("Content-Disposition: attachment;  filename=".basename($local_arquivo));
// Envia o arquivo Download
  readfile($local_arquivo);
}
?>

Pronto, o arquivo será baixado pelo usuário ao invés de ser aberto no navegador.

Bom, mas no exemplo dado acima, o arquivo baixar.php só funcionará para o determinado arquivo (iliada.pdf). E quando o site oferece muitos arquivos? É preciso criar um código para cada um, cada qual em um arquivo php próprio?

Não, felizmente! É possível usar a mesma página com a função (no nosso exemplo, baixar.php) para forçar o download de tantos arquivos quanto se queira. Para isso, o link precisará fornecer duas variáveis com os valores para o diretório e nome do arquivo. Além disso, será preciso fazer duas pequenas alterações na função original, ficando assim:

<?php
$arquivo = $_GET['arquivo']; // variável do nome do Arquivo
$local = $_GET['local']// variável do nome da pasta onde está o arquivo para download
$local_arquivo = $local.$arquivo; // Concatena diretório e arquivo

if (stripos($arquivo, './') !== false || stripos($arquivo, '../') !== false || !file_exists($local_arquivo)) {  // se há erro, do tipo, arquivo inexistente
  echo 'O comando não pode ser executado.'; // notifica o erro ao usuário
} else { // se não houver erro, prepara o arquivo para ser baixado
  header('Cache-control: private');
  header('Content-Type: application/octet-stream');
  header('Content-Length: '.filesize($local_arquivo));
  header('Content-Disposition: filename='.$arquivo);
  header("Content-Disposition: attachment;  filename=".basename($local_arquivo));
// Envia o arquivo Download
  readfile($local_arquivo);
}
?>

Ao contrário de nomear o arquivo, o código agora vai usar o valor da variável $_GET['arquivo'], que deve ser fornecido no link. O mesmo ocorre com o diretório local do arquivo que será baixado, que receberá o valor fornecido pela variável $_GET['local'].

Nossa função está pronta. Agora, é preciso configurar o link para que ele forneça os dois valores requeridos: arquivo (nome do arquivo) e local (onde o arquivo está armazenado).

A página de acesso ao usuário pode ter vários links, cada qual para um arquivo específico. Por exemplo, digamos que o site (por exemplo, na página index.php) contenha quatro arquivos diferentes disponíveis para download: então eu devo ter quatro links, todos remetendo o sistema para o arquivo da função (baixar.php), acrescidos com as duas variáveis e seus respectivos valores.

Nossos exemplos de links:

<a href="baixar.php?arquivo=oceano.mp3&local=musicas/">Baixar música</a>
<a href="baixar.php?arquivo=iliada.pdf&local=livros/">Baixar livro</a>
<a href="baixar.php?arquivo=troia.jpg&local=imagens/">Baixar imagem</a>
<a href="baixar.php?arquivo=programa.exe&local=downloads/">Baixar programa</a>

Observe que todos os links vão para o mesmo arquivo da função, mas cada link fornece valores diferentes para as variáveis arquivo local. No primeiro, temos o arquivo para download descrito como oceano.mp3 (portanto, um arquivo de áudio em MP3) e o local como musicas/ (que é onde deve estar o referido arquivo). Então, quando o arquivo da função for rodado, ele vai pegar os valores dessas variáveis ($_GET['arquivo'] e $_GET['local']) e efetuar o download perfeitamente.

Prático, eficiente e muito útil!

Nenhum comentário:

Postar um comentário