BuscaPé, líder em comparação de preços na América Latina

PHPit

Pular navegação

Limitando o número de downloads por cliente / pessoa / usuário / IP

Enviado em 24/03/2008 às 11:35

Prefácio

Rapidshare, MegaUpload, EasyShare, Zupload, Uploading, 4Shared... Quem nunca usou nenhum destes serviços que atire a primeira pedra. Não é tão intrigante o modo como eles conseguem fazer com que baixemos apenas um arquivo por vez? É muito bom saber que você consegue poupar uma porção de banda limitando o número de downloads cabeça!
Esta solução também provê um fim para o download utilizando aceleradores! :)

Os mais puristas irão indicar o módulo mod_limitipconn do Apache, mas se você estiver em uma hospedagem compartilhada, na maioria das vezes você não poderá mexer nos módulos do Apache.

Nessa dica iremos utilizar o mod_rewrite e um scriptzinho que irá gerenciar os downloads. Este também poderá ser adaptado para funcionar da mesma forma que o script gerenciador de downloads que foi desenvolvido em um dos últimos artigos, Forçar download ao invés da exibição.

Quem irá cuidar dos acessos de cada usuário será o nosso bom e velho MySQL (claro que você pode adaptar para PostgreSQL, Oracle, MS SQL Server, etc).

Mão na massa

A primeira coisa de todas é criar a nossa querida tabela. Vamos dar à ela o nome de baixando.

[sqlcode]CREATE TABLE `baixando` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`arquivo` VARCHAR(255) NOT NULL,
`ip` CHAR(15) NOT NULL,
`ultimoacesso` DATETIME NOT NULL,
) ENGINE=InnoDB[/sqlcode]

Agora precisamos do arquivo .htaccess. Caso você ainda não o conheça, você pode ler mais sobre ele neste artigo: Sobrescrevendo as configurações do php.ini com Apache e .htaccess.

Bom... Vamos supor que todos os arquivos estejam dentor da pasta arquivos. Você irá salvar o arquivo .htaccess neste diretório contendo as seguintes linhas:

RewriteEngine on
RewriteRule (.*)(zip|rar|pdf|exe)$ /arquivos/baixar.php [QSA]


Esta regra irá capturar todos os arquivos que forem acessados neste diretório, terminados em (zip|rar|pdf|exe), e irá cuidar para que todos eles sejam redirecionados para o arquivo baixar.php. É neste arquivo que devemos fazer a configuração para verificar se o fulano que está acessando tem permissão para tal.

E vamos à parte que estamos "acostumados":

  1. <?php
  2.  
  3. // Aqui você deve fazer a conexão com o banco! :P
  4.  
  5. // Caminho do arquivo que está sendo requisitado
  6. $caminho = mysql_real_escape_string($_SERVER['REQUEST_URI']);
  7.  
  8. // IP do indivíduo que está requisitando o arquivo
  9. $ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
  10.  
  11. // Está baixando?
  12. $baixando = false;
  13.  
  14. // Seleciona o último acesso em formato UNIX, equivalente ao mktime()
  15. $sql = "SELECT UNIX_TIMESTAMP(ultimoacesso) AS ultimavez FROM baixando WHERE arquivo = '$caminho' AND ip = '$ip' ORDER BY ultimoacesso DESC LIMIT 1";
  16.  
  17. $rs = mysql_query($sql);
  18.  
  19. if (mysql_num_rows($rs)) {
  20. $ultimaVez = mysql_result($rs, 0, 'ultimoacesso') + 1800;
  21. if ($ultimaVez < time()) {
  22. mysql_query("REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()");
  23. $baixando = true;
  24. }
  25. } else {
  26. $sql = "REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()");
  27. mysql_query($sql);
  28. $baixando = true;
  29. }
  30. ?>


Neste exemplo é utilizado um intervalo de 1800 segundos (meia hora) antes que o usuário possa baixar este arquivo novamente. Se o valor de $baixando for true.

E então segue o código que irá gerenciar o download! :)

  1. <?php
  2. if ($baixar) {
  3. $caminhoCompleto = $_SERVER['DOCUMENT_ROOT'].$path;
  4. if ($fp = fopen($caminhoCompleto, 'r')) {
  5. header ('Content-disposition:attachment;filename="'.basename($caminhoCompleto).'";');
  6. header ('Content-Length: '.filesize($caminhoCompleto));
  7. readfile($caminhoCompleto);
  8. exit;
  9. }
  10. } else {
  11. header('HTTP/1.0 503 Service Unavailable');
  12. print '<h1>503 Service Unavailable</h1><p>Você já baixou este arquivo demais!</p>';
  13. exit;
  14. }
  15. ?>


Com este código, o download só será possível se já tiver passado meia hora após a última vez em que este IP efetuou o download. E daí é só correr pro abraço! :P

Conclusão

Não é difícil de montar um sistema assim. Como em todos os tutoriais aqui, você pode desenvolver novas implementações e aumentar o potencial do script. Caso você utilize estes scripts como base ou caso você encontre algum erro, adoraria receber um comentário ou um e-mail seu!

Um grande abraço e fiquem com Deus.

 

Comente (06)




Comentário #1
Autor: Xorna
Em: 24/03/2008 às 20:47

Bah cara... que massa isso aí, eu fazia idéia de mais ou menos como fazer, mas não imagina que seriam somente esses passos =)

GENIAL

Comentário #2
Autor: Forbidencode
Em: 19/08/2008 às 16:36

A ideia é boa mas o seu codigo .................

Comentário #3
Autor: Rafael Jaques
Em: 19/08/2008 às 16:43

Olá Forbidencode.

Proponha uma abordagem melhor, por favor! :)

Um abraço!

Comentário #4
Autor: Sou
Em: 20/08/2008 às 01:00

Tentei executar o script funciona tudo, porém quando vou baixar, ele me retorno esse erro:

[function.fopen]: failed to open stream: No such file or directory in C:\site\baixar.php on line 35

Oq pode ser?

Valeu

Comentário #5
Autor: Rafael Jaques
Em: 20/08/2008 às 09:03

Provavelmente não está encontrando o arquivo... Você pode tentar verificar se o caminho está certo no .htaccess e também nos diretórios do seu site! :)

Comentário #6
Autor: Sou
Em: 22/08/2008 às 15:43

Consegui resolver o problema, porém estou com outro hehee
Quando acesso o script diretamente pelo browser. ex:

www.site.com.br/baixar.php

Ele pede para baixar o fonte do php hehe.
Porém o server está funcionando, rodando php normal o script está acessando o banco de dados, bloquecando a cada meia hora, tudo funciona.
Oq pode estár acontecendo?

Valeu

Artigos Recentes

Rafael Jaques - PHPit 2007
Site sob Creative Commons - Alguns direitos reservados

Assine o RSS do PHPit! :)
Saiba onde tem o melhor preço antes de comprar