PHP é a Quinta-Feira – HEADERs (parte 1)
Por Pedro Peixoto para o PPLWARE Depois de umas longas “férias”, hoje é dia de mais um artigo sobre “Programação WEB”, mais precisamente sobre PHP.
Na outra semana um amigo perguntou-me como poderia forçar o download de uma imagem, uma vez que sempre que colocava um link, o browser abria a imagem em vez de aparecer a “janelinha de download” como nos restantes ficheiros. Isto acontece porque existem diversos tipos de ficheiros que o browser consegue interpretar, e nesse caso, o ficheiro é mostrado imediatamente em vez de ser perguntado ao utilizador onde quer guardar o ficheiro para posteriormente o visualizar. É possível contornar este “automatismo” forçando o browser a questionar o utilizador sobre a sua intenção, para isso recorremos a headers.
O header é um componente da mensagem http que possui os parâmetros que definem essa transacção, esta informação não é visível numa página mas contém informação útil para o browser saber como interpretar a mensagem. Por exemplo o título que aparece no browser quando abrimos uma página é fornecido através do header.
Mas como manipulamos o header em imagens? Esta era uma pergunta complicada caso não tivéssemos a simplicidade e flexibilidade do PHP ao dispôr.
A ideia é a seguinte: vamos utilizar um ficheiro PHP para incorporar a imagem, no fundo este ficheiro PHP vai ser a nossa imagem.
Criei um ficheiro index.php numa pasta juntamente com o logótipo do pplware, se abrir a imagem através do browser ela naturalmente aparece
Para tornar o nosso index.php uma “imagem” precisamos de duas coisas, temos de dizer ao browser que o que vai ler é uma imagem e de seguida dar-lhe o código da mesma.
Podemos dizer-lhe que o conteúdo é uma imagem através da função header:
void header ( string $string [, bool $replace = true [, int $http_response_code ]] ) |
header() é usado para adicionar mais uma linha ao header http.
Para ler e apresentar o código da imagem recorremos à função readfile:
int readfile ( string $nomedoarquivo [, bool $use_include_path [, resource $context ]] ) |
Lê um arquivo e escreve o seu conteúdo para o buffer de saída (output buffer).
Vamos então escrever o seguinte código no ficheiro index.php.
<?php $ficheiro = "logo_pplware.png"; //nome do ficheiro header("Content-Length: " . filesize($ficheiro)); //tamanho esperado do ficheiro header('Content-Type: image/png'); //dizer ao browser que o conteúdo é uma imagem //agora que já enviamos os headers necessários vamos fazer o output da imagem readfile($ficheiro); //ler o código da imagem e fazer o output ?> |
E como esperado, se abrirmos a página vamos ver a imagem
O nosso “index.php” é, para o browser, uma imagem igual ao “logo_pplware.png”, este é um bom método para esconder o URL das imagens, e é também baseado neste método que a maior parte dos sites de downloads escondem o endereço real dos ficheiros, mas isto já poderia ser tema para um próximo artigo.
Nesta fase temos já a imagem a ser aberta através de um ficheiro PHP falta agora enviar mais um header que informe o browser para não interpretar directamente a imagem. Para isso basta adicionar mais uma linha ao nosso código.
header('Content-Disposition: attachment; filename=logo.png'); |
E aqui fica o código completo e devidamente comentado:
<?php $ficheiro = "logo_pplware.png"; //nome do ficheiro header("Content-Length: " . filesize($ficheiro)); //tamanho esperado do ficheiro header('Content-Type: image/png'); //dizer ao browser que o conteúdo é uma imagem //informamos que o conteúdo deve ser interpretado em forma de anexo, e o nome que queremos dar ao mesmo header('Content-Disposition: attachment; filename=logo.png'); //agora que já enviamos os headers necessários vamos fazer o output da imagem readfile($ficheiro); //ler o código da imagem e fazer o output ?> |
Resta testar e comprovar que a imagem já não é apresentada no browser e é enviada para a barra de downloads.
É igualmente possível apresentar outros tipos de ficheiro através de um ficheiro PHP, bastando alterar o campo “Content-type” do header:
"pdf": "application/pdf" "exe": "application/octet-stream" "zip": "application/zip" "xls": "application/vnd.ms-excel" "ppt": "application/vnd.ms-powerpoint" "gif": "image/gif" "png": "image/png" "jpg": "image/jpg" "mp3": "audio/mpeg" "mp3": "audio/mp3" "wav": "audio/x-wav" "mpe": "video/mpeg" "mov": "video/quicktime" "avi": "video/x-msvideo" |
Além disso existem muitos mais campos de header que podem ser manipulados de forma a obter do browser um tratamento mais apropriado a cada tarefa específica.
Nos próximos artigos vou explicar como é possível tirar partido do header para outras finalidades e como possibilitar o download de um ficheiro durante apenas uns minutos, ao estilo dos sites de download.
Este artigo tem mais de um ano
Interessante…
Excelente artigo Pedro. Já cá fazia falta esta rubrica.
Pois faz falta, é muito útil. o próximo artigo podias falar sobre atribuição condicional, acho bastante interessante 🙂
Atenção que é o Pedro Peixoto..Eu (Pedro Pinto) ando sempre por cá..:)
Fico à espera do próximo. O tema parece interessante. Claro que este também foi.
dicas muito interessantes. ja estava com saudades desta rubrica. I love php. lol. Que venha mais.
alguem da pplware que apague este comentario e o anterior brigado.
dicas muito interessantes. ja estava com saudades desta rubrica. I love php. Que venha mais.
Bem-vindo de volta PHP!!!! Já estava com saudades 😉
Continua com estes artigos…
Uma dica, para um dos próximos artigos: a criação de ficheiros em PHP. Pode ser por exemplo um export do resultado de uma query e gravar num ficheiro de texto e/ou em zip.
Realmente interessante 🙂
Já estava assustado! Pensava que a rubrica tinha acabado! 🙁 Felizmente não! =D
Muito bom artigo.
Só um pequeno pormenor:
Neste caso a imagem é do tipo “image/png”.
O IE 8, ao contrário do 7 e do 9, não reconhece este tipo de imagem, mas sim “image/x-png”.
Não experimentei, mas penso que este exemplo não funcionará no IE8. Teríamos que acrescentar uma regra extra caso se esteja a usar este browser.
Boas. Eu ja testei isso e funciona mas tenho um problema. Eu estou a realizar a minha PAP usando um gestor de conteúdos (WordPress) e ele nao me deixa mexer com os headers, logo nao me faz o download. Podem ajudarme?
Valeu demais!!!
“Salvou minha vida” !!!!
Parabéns
Tudo funcionando Lindamente, PORÉM…
Quando tento visualizar os arquivos no SAFARI a tela fica vazia 🙁
Alguém pode me ajudar ?