PHP é à quinta-feira – Download de um ficheiro

27 Comentários

Boas,

A nível de direitos sobre o código, devo-vos remeter para o meu primeiro artigo desta rubrica.

Hoje trago-vos um script (que podem facilmente transformar numa função) que força o browser de um visitante a fazer download de um ficheiro.

<?php 

$file = "/caminho/para/o/ficheiro.pdf";
$attachment_name = "nome_para_download.pdf"; 

$file_extension = strtolower(substr(strrchr($file,"."),1));
$ext = substr(strrchr($file,"."),1); 

switch( $file_extension ) {
   case "pdf": $ctype="application/pdf"; break;
   case "exe": $ctype="application/octet-stream"; break;
   case "zip": $ctype="application/zip"; break;
   case "odt": $ctype="application/vnd.oasis.opendocument.text";break;
   case "doc": $ctype="application/msword"; break;
   case "ods": $ctype="application/vnd.oasis.opendocument.spreadsheet";break;
   case "xls": $ctype="application/vnd.ms-excel"; break;
   case "odp": $ctype="application/vnd.oasis.opendocument.presentation";break;
   case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
   case "gif": $ctype="image/gif"; break;
   case "png": $ctype="image/png"; break;
   case "mp3": $ctype="audio/mpeg3";break;
   case "wav": $ctype="audio/wav";break;
   case "mpeg":
   case "mpg": $ctype="video/mpeg";break;
   case "avi": $ctype="video/avi";break;
   case "jpeg":
   case "jpg": $ctype="image/jpg"; break;
   default: $ctype="application/force-download";
} 

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: ".$ctype."");
header("Content-Disposition: attachment; filename=\"".$attachment_name."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
readfile($file);
exit();

?>

Modo de utilização:

Em cima está descrita uma forma de utilizar para fazer download do ficheiro “/caminho/para/o/ficheiro.pdf” sob o nome “nome_para_download.pdf”

Qualquer dúvida ou sugestão, estão completamente à vontade.

Comentários

27

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

  1. Avatar de Rui

    Boa tarde,

    É sempre bom verificar opiniões e técnicas de programação. A este script adiciona-se a ligação a uma base de dados e incrementa-se o nº de downloads para sabermos que interesse existe por parte de alguém nos nossos documentos.

    Se precisarem de ajuda para umas “postadas” na rubrica PHP, avisem-me, ok?

    1. Avatar de Bruno Bernardino

      Cuidado com o que dizes! Estás mesmo disponível para ajudar? 🙂 Olha que se torna um compromisso! 😀

      1. Avatar de João
        João

        Tens algum script para upload de imagens num servidor tipo rapidshare ou cousa assim? Cumprimentos

        1. Avatar de Bruno Bernardino

          Basta pesquisares no Google por algo como “file upload script” ou “rapidshare clone script” que encontras o que procuras 🙂

    2. Avatar de Lucas Pedro

      Voce falou que está a disposição !! rsrsrsrs

      Preciso de um gerenciador de ficheiros para uploads de arquivos … que quando voce enviar um arquivo ele renomeie , com uma id sequencial

      se alguem puder me ajudar agradeço !!

  2. Avatar de Pouic

    Obrigado pela dica, dá sempre jeito 😀

  3. Avatar de Miguel Guerra
    Miguel Guerra

    Boa dica para permitir downloads só a pessoas autorizadas, por exemplo.

  4. Avatar de Marcio Henrique

    Boa dica, mas nesta linha por exemplo:
    case “jpg”: $ctype=”image/jpg”; break;

    Isto quer dizer que é permitido o download de um ficheiro .jpg
    Ora, um utilizador mais experiente consegue saber os caminhos, sejam absolutos ou relativos para um .jpg e fazer o download do mesmo sem autorização.
    Por isso este post poderia ser melhorado, exemplificando como fazer com o .htaccess para que o “hotlinking” de ficheiros .jpg nao sejam permitidos.

    Seja como for, bom post.

    1. Avatar de softclean
      softclean

      Com este método, não sabes necessariamente onde está o ficheiro no servidor, porque este é lido pelo PHP e despejado no browser, mas tens razão quanto ao hotlinking, pois é sempre possível aceder-lhe.

      Podem inclusive verificar o referrer e bloquear tudo o que seja fora do domínio. Tirando referrers forjados, funciona muito bem.

      E um bem haja para esta secção, espero um dia contribuir com um código interessante! 😀

    2. Avatar de Pedro A.
      Pedro A.

      Pelo que percebi o exemplo é para forçar o download de um ficheiro quando se carrega uma página e o switch serve para indicar ao browser qual o tipo de ficheiro para sacar. No caso do ficheiro ser um JPG, o browser é informado que o ficheiro é do tipo image/jpg. Como resultado o browser vai fazer o download da imagem em vez de a mostrar na página…

  5. Avatar de carlos rajas
    carlos rajas

    Alto nível Bruno, keep it up !!!

  6. Avatar de Bruno Bernardino

    Se tiverem sugestões, podem enviar para o Pplware, depois de uma triagem chegará a mim 🙂

  7. Avatar de Hugo Sousa

    Bom tutorial. Simples, prático e principalmente: útil!

    Tenho apenas dois detalhes a apontar:
    1 – A variavel $ext foi declarada e assignada, mas nunca utilizada. 🙂
    2 – Colocaste o post na categoria CSharp, quando penso que a tua ideia era colocar na de PHP.

    Cumprimentos, continua o bom trabalho!

  8. Avatar de Edgar Sousa
    Edgar Sousa

    Uma coisa só: se a ideia é forçar o browser a fazer o download é usar sempre o tipo “application/octect-stream”.

    Em alguns casos o browser vai ignorar o “Content-Disposition: attachment” e vai lançar o plugin na mesma (Acrobat Reader e o IE costumavam-me dar esse problema)

    1. Avatar de Hugo Pinto
      Hugo Pinto

      Exactamente. Só faz sentido estar a indicar os vários MIME se se quer permitir que o browser carrege o visualizador respectivo, de resto é tudo com “application/octect-stream”

      1. Avatar de Bruno Bernardino

        O objectivo é esse, que o browser saiba como interpretar.

        Por exemplo no firefox se não tiver o Mime-type, um ficheiro pdf só permite o download, mas se tiver o Mime-type, já permite o “Abrir” para ver com o programa apropriado (sem ser dentro da janela do browser)

  9. Avatar de aospapeis.blogspot.com

    Deixem-me dar-vos uma sugestão: escrevam um artigo sobre ColdFusion. Embora, hoje, já não faça praticamente nada nesta linguagem (porque o servidor é pago…), a verdade é que todos os dias sinto saudades da gigantesca facilidade de programação, da simplicidade do código, da sua potência, e do facto de haver uma maneira “oficial” para fazer seja o que for.

    ColdFusion – informem-se

    1. Avatar de Bruno Bernardino

      Quem me conhece sabe que não só sou adepto do open-source, como principalmente não sou a favor do software proprietário.

      Como tal, se pretendes um artigo sobre ColdFusion, envia para o Pplware que teremos todo o gosto em o publicar 🙂

  10. Avatar de Pedro
    Pedro

    esse script é o mais básico para download. não tem suporte para resumir download, não detecta quando o utilizador cancela o mesmo, são só os exemplos mais notórios de falhas.

    1. Avatar de Bruno Bernardino

      Com server-side isso não é possível, mas podes enviar a sugestão que fizeste para o Pplware, agradecemos e ficamos à espera. 🙂

  11. Avatar de carlos
    carlos

    so 1 observaçao, a categoria esta em csharp deva tar em php.

  12. Avatar de Cristina Branco
    Cristina Branco

    Parabéns pelo post estava mesmo a necessitar desta validação para o upload de ficheiros do tipo pdf, contudo precisava de um que aceita-se documentos word 2007, visto que o aplication /msword só aceita word 2003.

    Muitos parabéns

    1. Avatar de Bruno Bernardino

      Neste site podes ver os Mime-types de qualquer ficheiro.

      Neste caso, docx: http://filext.com/file-extension/DOCX

  13. Avatar de Fabio
    Fabio

    Como possa fazer para abrir para download em computadores Linux?
    Pois o DOC não abre como download.

    1. Avatar de Bruno Bernardino

      Comentas ou removes a linha do doc, para ficar $ctype=”application/force-download”

      1. Avatar de João Azevedo
        João Azevedo

        Boas Bruno,
        Ao longo deste conversa apercebi-me que tens grandes conhecimentos no que diz ao php e como tal gostava de lhe pedir ajuda com um trabalho que estou a desenvolver.
        Estou a desenvolver um site em que permite listar imagens de uma base de dados e agora o que eu queria era poder seleccionar as fotos com uma “checkbox” e no fim fazer download de todas as fotos seleccionas.
        Pode ajudar-me?

        1. Avatar de Bruno Bernardino

          Olá João,

          A melhor forma de obteres ajuda é no Fórum do Pplware http://forum.pplware.com lá podes contar com a minha ajuda e de muitas mais pessoas 😉

          Respondendo rapidamente à tua pergunta, podes guardar num array as imagens guardadas (bastará dares o mesmo nome às checkboxes, algo como name=”selectedImages[]”), comprimi-las e retornar ao browser.