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!

quinta-feira, 4 de agosto de 2016

.HTACCESS - Segurança para a sua Web


Em tempos de terrorismo virtual, nada mais natural do que cuidar da segurança do seu site. Para tanto, é imprescindível fazermos bom uso do arquivo .htaccess, que, além de precauções contra má intenções de usuários espertos (leia-se hackers), oferece recursos diversos muito úteis. Vamos conhecê-los!

O .htaccess é basicamente um arquivo de configuração utilizado em servidores web, como Apache. Seu nome vem de Hypertext Access = acesso os hipertextos. O arquivo funciona a nível de diretórios e permite que administradores gerenciem e manipulem configurações e acessos de forma descentralizada.


As configurações presentes nesse arquivo são aplicadas ao diretório no qual ele se encontra e também a todos os seus subdiretórios, caso existam. Vale lembrar ainda que a presença de um outro .htaccess em um subdiretório anula a ação do que se encontra um nível acima. Ou seja, o .htaccess do subdiretório passa a valer para o mesmo e também para todas as suas subpastas. E assim por diante. É sempre bom ficarmos atentos a estes detalhes.


CRIAR UM ARQUIVO .HTACCESS

Crie um arquivo .htaccess facilmente usando um editor de texto qualquer, por exemplo o Bloco de Notas padrão do Windows. Salve-o como “.htaccess” (sem aspas e com o ponto antes do nome) sem extensão ao final. Logo, nada de “.htaccess.txt”, mas simplesmente ".htaccess". Nós o colocaremos no diretório raiz da nossa web.


PROTEGENDO O .HTACCESS

Primeiramente, proteja o seu arquivo configurador de inserções malévolas ou equivocadas com as seguintes instruções:

<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>



PERSONALIZANDO PÁGINAS ESPECIAIS

Com ele, você pode personalizar páginas especiais, por exemplo, a página de erro ("404 Not Found") e de redirecionamento em caso de falha do servidor (500). No nosso exemplo, vamos estabelecer uma pasta exclusiva para eles denominada "erros".

# páginas especiais
ErrorDocument 400 /erros/badrequest.html
ErrorDocument 401 /erros/authreqd.html
ErrorDocument 403 /erros/forbid.html
ErrorDocument 500 /erros/serverr.html



BLOQUEANDO LISTAGEM DE DIRETÓRIOS E ARQUIVOS

Você pode também utilizar o .htaccess para evitar a listagem de diretórios. Para evitar que o conteúdo de um diretório seja exibido quando algum usuário o acessar, por exemplo, quando o usuário usa um comando  do tipo www.seusite.com.br/nomedapasta” ou “www.seusite.com.br/imagens”.
Basta somente adicionar o snipper seguinte:

# não indexar diretórios
Options -Indexes



CONTROLANDO O ACESSO A DIRETÓRIOS

Evite que você terceiros acessem determinados arquivos e pastas em seu site. Você possui um script qualquer instalado, por exemplo, e deseja evitar que visitantes acessem sua pasta “includes”. Mas, por outro lado, você precisa garantir que qualquer página do site em questão possa “chamar” sem problemas os arquivos contidos nesta pasta. Basta, então, adicionar um .htaccess com o seguinte conteúdo na tal pasta, no caso, a “includes”:

# acesso restrito
deny from all

Caso queira abrir exceção para um determinado IP, use o bloco a seguir:

# Acesso restrito!
order deny,allow
deny from all
allow from
NÚMERO DO IP



DEFININDO A PÁGINA INICIAL DO SITE

Defina que página deve abrir quando o usuário acessar sua web. O padrão é index.html ou index.php, mas você optar por outra qualquer, por exemplo empresa.php

A ordem a ser dada é:

# página inicial
DirectoryIndex index.html index.php index.html

No exemplo acima, os arquivos index.htm, index.html e index.php serão considerados como páginas de índice, obedecendo essa ordem. Ou seja, o sistema vai procurar por index.htm e, caso não a encontre, passará a procurar pela próxima indicada.
Se quiser informar outra, siga o mesmo procedimento:

# página inicial
DirectoryIndex empresa.html

Pelo exemplo acima, quando o usuário visitar o seu domínio, por exemplo, www.seusite.com.br, ele será automaticamente redirecionado para www.seusite.com.br/empresa.html.



URL AMIGÁVEIS


Com .htaccess, você também pode reescrever URLs para torná-las mais amigáveis, tanto para os motores de busca quanto para os visitantes.

Por exemplo, vamos dizer que você tem uma loja virtual e nela venda diversos produtos. Digamos, agora, que suas URLs possuem a seguinte estrutura:
http://www.meusite.com/produto.php?id=12

Simplifique a estrutura do exemplo para apenas:
http://www.meusite.com/produto-12.html

Então, reescreva produto.php?id=12 para produto-12.html fazendo assim:


RewriteEngine on
RewriteRule ^produto-([0-9]+)\.html$ produto.php?id=$1

Reescrevendo produto.php?id=12 para produto/hub-usb/12.html:

RewriteEngine on
RewriteRule ^produto/([a-zA-Z0-9_-]+)/([0-9]+)\.html$ produto.php?id=$2



REMOVENDO EXTENSÕES DE URLS

Remova a exibição das extensões dos arquivos das URLs, por exemplo, ao invés de seu visitante visualizar algo como contato.php na barra de endereços do navegador, ele pode visualizar simplesmente contato.

Faça isso acrescentando no .htaccess:

# removendo extensão php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

No exemplo acima, a extensão .php será removida/escondida. Você pode também usar o mesmo snippet para esconder outras extensões de arquivos, como por exemplo .html. Basta realizar as devidas substituições.



FORÇAR DOWNLOAD DE CERTOS ARQUIVOS

Você pode forçar que um determinado tipo de arquivo (por exemplo os livros digitais em PDF) seja baixado pelo usuário, ao invés de esse arquivo ser executado direto.
Isso pode ser feito assim:

# forçar download de PDF
AddType application/octet-stream .pdf



FORÇAR TEXTO EM UTF-8

Para evitar problemas de codificação e renderização de páginas por causa da codificação de texto, force o uso da codificação UTF-8, padrão para nosso idioma:

#forçar UTF-8
<FilesMatch ".(php|htm|html|css|js)$">
AddDefaultCharset UTF-8
</FilesMatch>