【问题标题】:Limt the amount a user downloads from a website, and redirect when limit is reached?限制用户从网站下载的数量,并在达到限制时重定向?
【发布时间】:2011-12-07 17:37:29
【问题描述】:

抱歉,标题含糊不清!我有一个包含大量 PDF 文件且每月带宽有限的网站。我想要实现的(在 PHP 中)是一种将每个用户($_SESSION?)限制在一定限度内的方法 - 比如 50MB,当他们点击下载另一个文件时,他们将被重定向到拒绝任何用户的网页进一步下载(比如接​​下来的 24 小时)。

这可能吗?我不确定我的下载“计数器”是否只能计算 .pdf 文件(如果访问者达到限制,我不希望访问者被阻止浏览该站点)。任何伪代码将不胜感激。

【问题讨论】:

    标签: php download limit


    【解决方案1】:

    如果您的所有下载都通过一个 php 脚本进行:

    <a href="download.php?file='filename.pdf'" />
    

    你几乎可以做任何你想做的事。该 php 文件可以传递您的所有文件(将它们排除在 webroot 之外),写入您的 _SESSION,它可以执行您的重定向。享受吧。

    【讨论】:

      【解决方案2】:

      如果您已经有用户系统,我建议您将所有信息存储在用户配置文件中。

      因此,如果他删除所有 cookie 并重新登录,就没有问题!

      对于客人,我建议使用验证码和基于会话或 IP 的限制。

      // Pseudo code
      // download.php
      
      function UserHasReachedLimit($file)
      {
        $info = $Database->QueryUserInfo('limit');
        $max = $Database->GetLimitForFile($file);
      
        if ( $info[$file] > $max )
          return false;
        else 
          return true;
      }
      
      if ( IsUser() )
      {
        if ( UserHasReachedLimit() )
          error();
        else
          download();
      }
      else // guest
      {
        // session or IP based restrictions...
      }
      

      【讨论】:

      • 感谢您的回复。我没有用户系统,它似乎超出了网站的范围/大小,但我会记住这一点。我想这会留下 SESSION / IP 限制(尽管有 Digital Precision 的警告)。在伪代码方面,谁能给我一些想法?我在想 download.php?file='foo.pdf' download.php 检查 IP,恢复会话,获取文件大小与限制相比并允许/拒绝下载。但是我如何在一天后清除会话?其余的合理吗?
      【解决方案3】:

      我可能会为此远离会议。会话是易变的并且容易受到各种浏览器行为的影响。例如,在 Firefox 中,如果会话被初始化,我可以关闭 Firefox,访问同一个站点,并且会话仍然处于活动状态。但是在 IE 中,如果我打开多个选项卡并访问同一个站点,每个选项卡式实例都会获得一个新的会话 ID。

      我建议设置一个用户必须登录到您的网站的帐户系统。然后您可以在帐户级别跟踪他们的下载量,这将在多个会话之间持续存在。

      【讨论】:

        【解决方案4】:

        我认为你试图避免强迫用户在你的网站上注册,而你试图用常见的方式(cookies、ip ...)跟踪每个访问者的带宽是不切实际的。所以,最好的方法(在我看来,当然有很多改进的解决方案)是制作一个简单的注册表单,比如姓名、密码和电子邮件,在每封电子邮件中放置一个激活系统,以保护您的网站免受用户的侵害,现在每个用户登录并尝试下载文件,您按以下步骤处理他的请求:

        1) 用户对文件名.pdf 的请求(检查其可用性和大小(重要))。

        2) 检查用户带宽:

        $query = sql_query("SELECT Bandwidth, LastDownload FROM Users, Stats WHERE USER_ID=5");
        $result = sql_fetch($query);
        if ($result['Bandwidth'] < 50M)
        showDownloadLink();
        else if($result['LastDownload'] - currentTime() !=0)
        echo "please wait to the next 24h";
        

        数据库应该是这样的: 用户:

        ID_U int(key, auto increment), Name varchar(25), email varchar(255), password varchar(32), Bandwith float
        

        统计:

        ID_S int(key, auto increment), LastDownload time, ID_U integer
        

        注意: 每次用户下载文件时,您都会为正确的用户更新带宽行,以便稍后您可以检查特定用户是否达到其限制。您还必须在每 24 小时后重置它。

        这是一个通用的解决方案,许多人认为必须检查,例如计数器带宽必须每 24 小时重置一次。

        【讨论】:

          【解决方案5】:

          创建一个表来存储下载次数

          CREATE TABLE IF NOT EXISTS `downloaded` (
            `ip` varchar(200) NOT NULL,
            `count` int(11) NOT NULL DEFAULT '0',
            `last_access` datetime DEFAULT NULL,
            UNIQUE KEY `ip` (`ip`)
          ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
          
          <?php
          
          /*
          $limit  => Number of Downloads Allowed
          $period => In minutes
          
          */
          function UserHasReachedLimit($limit, $period) {
          $ip = addslashes($_SERVER['REMOTE_ADDR']);
          $dl = false;
          $sql = sprintf("SELECT UNIX_TIMESTAMP(last_access) last_time, count FROM downloaded WHERE ip = '%s' ORDER BY last_access DESC", $ip);
          $res = mysql_query($sql);
          
          if (mysql_num_rows($res) > 0) { // There is a registered IP already
              $last_xs = mysql_result($res, 0, 'last_time');
              $last_xs += $last_xs+$period * 60;
              $count = mysql_result($res, 0, 'count'); // number of downloads by this ip
              if ($count == $limit && $last_xs > time()) { // we check if downloads reached in this period
              $dl = true;
              } else {
              $sql = sprintf("UPDATE downloaded SET count = CASE WHEN count >= %s THEN 0 ELSE count+1 END, last_access=now() WHERE ip ='%s'", $limit+1, $ip);  // we just update download count + 1
              mysql_query($sql);
              }
              } else { // There is not a registered IP and we create it
              $sql = sprintf("INSERT INTO downloaded VALUES ('%s', '0', NOW());", $ip); mysql_query($sql);
              }
          return $dl;
          }
          
          
          /*
          Usage
          */
          $limit = 2;
          $period = 2;
          if(UserHasReachedLimit($limit, $period) == true) {
          // User reached number of 2 downloads in 2 minutes
          
          } else {
          // Continue downloading
          
          }
          
          
          
          ?>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多