2013-04-11 52 views
1

这是关于使用php脚本从服务器下载文件的问题。当用户点击下载链接时,它处理为download.php文件,并使用header开始下载。使用php脚本下载文件,一次在

下载文件后,是download.php文件中的一个功能,它从用户的账户更新mysql数据库中有关下载的文件和扣钱。一切正常。

现在,用户在PC上安装下载管理器时会出现问题。有时下载开始在浏览器和下载管理器中。因此,最后在数据库中有两个下载条目,并且两次从用户帐户中扣除了钱。

问题:有什么办法在时间只启动一个下载?或者任何其他方式来做这件事?

我提供给用户的下载链接。

<a href='download.php?id=1'>Download Test Video</a> 

我用于下载文件的脚本。 (的download.php)

$file = "c:/test.avi"; // $file = $_GET['id']; 
    $title = "Test Video"; 

    header("Pragma: public"); 
    header('Content-disposition: attachment; filename='.$title); 
    header("Content-type: ".mime_content_type($file)); 
    header("Content-Length: " . filesize($file) ."; "); 
    header('Content-Transfer-Encoding: binary'); 
    ob_clean(); 
    flush(); 

    $chunksize = 1 * (1024 * 1024); // how many bytes per chunk 
    if (filesize($file) > $chunksize) { 
     $handle = fopen($file, 'rb'); 
     $buffer = ''; 

     while (!feof($handle)) { 
      $buffer = fread($handle, $chunksize); 
      echo $buffer; 
      ob_flush(); 
      flush(); 
     } 

     fclose($handle); 
    } else { 
     readfile($file); 
    } 

    record_download('user id', 'file id'); 
+1

这可能会派上用场...... http://stackoverflow.com/questions/14233850/how-to-prevent-file-hotlink-from-internet-download-manager-idm ..我们的想法是阻止这些下载管理器..还有其他想法。但是,这是其中之一... – 2013-04-11 04:56:11

+0

您是否对视频的每个下载付费?您最好拥有按次收费的视图并将其嵌入到您的网页中,不是吗?如果您对整个视频进行收费,只需让客户“购买”一个视频,然后根据需要多次下载(或对其设置限制) – 2013-04-11 04:57:25

+4

不太确定您将如何为用户安装此设置,但我最近完成了类似的事情。当他们去下载时,会显示一个唯一的URL(下载/ ),他们将使用它。如果他们试图再次处理,则会使用前一个标记。当然,这只适用于活动会话时。 – Dave 2013-04-11 05:02:21

回答

1

将评论移到此处以供有兴趣的人使用。

,我不得不拿出是一个独特的下载链接付款进行了处理后的功能。这些是已采取的步骤。

  • 处理付款并捕获可下载文件的IP地址,文件和路径 - 将此信息保存到数据库。
  • 一旦付款成功扣除,触发生成一个唯一的令牌的功能,e.g:sha1(microtime().$transactionid),这保存到数据库中(注意:请不要在生产中使用microtime中(),使用一个随机字符串发生器)。
  • 使用.htaccess我们生成一个下载链接,例如:http://domain.com/download/<token>的。htaccess的内容:

    RewriteRule ^download/([a-z0-9-]) /download.php?token=$1 
    
  • 可选:如果他们的IP匹配我们所拥有的数据库,继续前进,允许用户下载该文件。如果没有,我们要求用户登录,以便我们可以更新他们的IP地址并开始下载。
  • 一旦你有了令牌,你几乎可以从这里进行任何形式的验证,比如通过在数据库中添加一列来防止多次下载download_downloaded INT(1) DEFAULT 0如果它被设置为1,那么它已被下载。我建议给用户一天前下载后锁定它们,以防万一他们的文件在这个过程中被破坏。
  • 任何其他附加项目,如下载计数器等。
  • 最后使用您的代码以上后开始下载。但我会让它的结构有点不同。

的download.php

$token = $_GET['token']; 
$allow_download = FALSE; // Can never be too careful.. 

... 
//Database lookup to get the file ID 
... 

$file = "c:/test.avi"; // now from the database call 
$title = "Test Video"; 

// Do any additional validation here 
// returns TRUE or FALSE (Boolean) -- Custom function to query the database 
$allow_download = check_if_downloadable('user_id', 'file_id', 'token_id'); 
record_download('user id', 'file id'); 

// After validation is complete, allow them to download 
if ($allow_download === TRUE){ 
    header("Pragma: public"); 
... 

如果用户丢失了他们的下载链接(因为它已经发生过很多次),我们将展示他们的会员主页的下载链接,一旦他们登录,并且他们可以再次开始下载(如果允许的话)。

我希望这会有所帮助。很抱歉,我目前无法提供一些代码示例。

大部分这只是查询数据库。

0

我会建议改变的逻辑:第一

但有一个安全漏洞!

如果两个人开始与该链接下载文件,那么他们可以绕过支付一个。 但是,如果有人下载该文件并将其发送给其他人,该怎么办。所以,这不是什么问题。不是吗?

但是如果你认为你应该真的很安全,那么有一个选项附加CSRF令牌。

1

有时在我们的网站上,需要下载链接。当点击这个链接时,任何类型的文件,图像,PDF将被下载。你可以使用一个简单的PHP脚本来做到这一点。

想要下载图片名称“shafiq_photo.jpg”,所以参数是文件名“shafiq_photo.jpg”。 然后在上面的文件中创建一个php文件名“download.php”。

<?php 
$file = $_GET["file"]; 

if (file_exists($file)) { 
header('Content-Description: File Transfer'); 
header('Content-Type: application/octet-stream'); 
header("Content-Type: application/force-download"); 
header('Content-Disposition: attachment; filename=' . urlencode(basename($file))); 
// header('Content-Transfer-Encoding: binary'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($file)); 
ob_clean(); 
flush(); 
readfile($file); 
exit; 
    } 
?>