As vezes queremos que apareça a janela de download em certos links de nossas páginas. Mais isso as vezes não ocorre, pois alguns formatos de arquivos abrem diretamente em outros programas ou até mesmo no navegador (isso depende da versão do navegador). Um exemplo disso são os arquvos PDF, JPG, MP3 entre outros.

Como esse script podemos forçar o download desses arquivos sem ter o problema mensionado acima.

Crie um arquivo PHP chamado "baixar.php" e coloque o seguinte código:


   $arquivo = $_GET["arquivo"];
   if(isset($arquivo) && file_exists($arquivo)){ 
   // faz o teste se a variavel não esta vazia e se o arquivo realmente existe
      switch(strtolower(substr(strrchr(basename($arquivo),"."),1))){ 
      // verifica a extensão do arquivo para pegar o tipo
         case "pdf": $tipo="application/pdf"; break;
         case "exe": $tipo="application/octet-stream"; break;
         case "zip": $tipo="application/zip"; break;
         case "doc": $tipo="application/msword"; break;
         case "xls": $tipo="application/vnd.ms-excel"; break;
         case "ppt": $tipo="application/vnd.ms-powerpoint"; break;
         case "gif": $tipo="image/gif"; break;
         case "png": $tipo="image/png"; break;
         case "jpg": $tipo="image/jpg"; break;
         case "mp3": $tipo="audio/mpeg"; break;
         case "php": // deixar vazio por seurança
         case "htm": // deixar vazio por seurança
         case "html": // deixar vazio por seurança
      }
      header("Content-Type: ".$tipo); 
      // informa o tipo do arquivo ao navegador
      header("Content-Length: ".filesize($arquivo)); 
      // informa o tamanho do arquivo ao navegador
      header("Content-Disposition: attachment; filename=".basename($arquivo)); 
      // informa ao navegador que é tipo anexo e faz abrir a janela de download, 
      //tambem informa o nome do arquivo
      readfile($arquivo); // lê o arquivo
      exit; // aborta pós-ações
   }
?>

Agora crie um arquivo html "index.html" e coloque o seguinte código:


<!--<br color:="" rgb(0,="" 102,="" 255);"="">  Este será o link que apontará para o 
nosso script PHP.<br color:="" rgb(0,="" 102,="" 255);"="">  Use no href 
"baixar.php?arquivo=" + caminho de seu arquivo;<br color:="" rgb(0,="" 102,
="" 255);"="">  No Exemplo abaixo utilizei uma imagem com o nome "imagem.jpg" 
que esta dentro da pasta "arquivos".<br color:="" rgb(0,="" 102,="" 255);"
="">--><br color:="" rgb(0,="" 102,="" 255);"=""><a href="baixar
.php?arquivo=arquivos/imagem.jpg">Baixar Arquivo</a>

Agora execute o "index.html" e clique no link "Baixar Arquivo". Irá aparecer a janela de download.

Solução proposta pelo usuário Robson Silva

Em termos de segurança, acho que dava pra melhorar o código, adicionando o trecho abaixo logo no inicio do script.


$arquivo = $_GET["arquivo"]; 

$testa = substr($arquivo,-3); 
$bloqueados = array('php','tml','htm'); 
// caso a extensão seja diferente das citadas acima ele 
// executa normalmente o script 

if(!in_array($testa,$bloqueados)){ 

// aqui vai o código completo 

}else{echo "Erro!";exit;} 

Solução proposta pelo usuário Douglas Lopes

Quando a extensão do arquivo tiver mais de 3 caracteres, seria necessária uma readaptação da função substr(). Eu prefiro utilizar a função pathinfo() pra recuperar a extensão, ex:


$arquivo = 'nome.txt'; 
$arquivo = pathinfo($arquivo); 

$bloquados = array('php', 'html', 'htm', 'asp'); 

if(!in_array($testa,$bloqueados)){ 

// aqui vai o código completo 

}else{echo "Erro!";exit;} 

Assim, não importa o tamanho da extensão, sempre vai retornar por completo.

Nota: A função explode() também cumpriria bem esse papel, mas se houvesse pontos no nome do arquivo poderia ter algum problema.