使用php脚本下载文件,一次一个

时间:2013-04-11 04:50:54

标签: php download

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

下载文件后,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');

3 个答案:

答案 0 :(得分:2)

将评论下载到任何感兴趣的人。

我必须提出的功能是在处理完付款后的唯一下载链接。这些是采取的步骤。

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

    RewriteRule ^download/([a-z0-9-]) /download.php?token=$1
    
  • 可选 :如果他们的IP与我们在数据库中的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");
...

如果用户丢失了下载链接(因为它已经多次发生),我们会在他们登录后在其成员主页上显示他们的下载链接,并且他们可以再次开始下载(如果您允许)。

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

大部分只是查询数据库。

答案 1 :(得分: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;
   }
 ?>

答案 2 :(得分:0)

我建议改变逻辑:

但是有一个安全漏洞!

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

但如果您认为自己应该非常安全,可以选择附加CSRF令牌。