2009-02-17 97 views
1

我试图建立与可投票的新闻链接一个网站,我有以下代码:如何在我的网站上实施投票系统,将投票限制为一票?

case 'vote': 
       require_once('auth/auth.php'); 
       if(Auth::isUserLoggedIn()) 
       { 
        require_once('data/article.php'); 
        require_once('includes/helpers.php'); 

        $id = isset($_GET['param'])? $_GET['param'] : 0; 
        if($id > 0) 
        { 
         $article = Article::getById($id); 
         $article->vote(); 
         $article->calculateRanking(); 
        } 
        if(!isset($_SESSION)) session_start(); 
        redirectTo($_SESSION['action'], $_SESSION['param']); 
       } 
       else 
       { 
        Auth::redirectToLogin(); 
       } 
       break; 

现在的问题是,如何检查,以便同一个用户不投两次票,这里是文章文件:

<?php 
require_once($_SERVER['DOCUMENT_ROOT'].'/config.php'); 
require_once(SITE_ROOT.'includes/exceptions.php'); 
require_once(SITE_ROOT.'data/model.php'); 
require_once(SITE_ROOT.'data/comment.php'); 

class Article extends Model 
{ 
    private $id; 
    private $user_id; 
    private $url; 
    private $title; 
    private $description; 
    private $ranking; 
    private $points; 

    function __construct($title = ' ', $description = ' ', $url = ' ', $username = ' ', $created = ' ', $modified = '') { 

     $this->setId(0); 
     $this->setCreated($created); 
     $this->setModified($modified); 
     $this->setUsername($username); 
     $this->setUrl($url); 
     $this->setTitle($title); 
     $this->setDescription($description); 
     $this->setRanking(0.0); 
     $this->setPoints(1); 
    } 

    function getId(){ 
     return $this->id; 
    } 

    private function setId($value){ 
     $this->id = $value; 
    } 

    function getUsername(){ 
     return $this->username; 
    } 

    function setUsername($value){ 
     $this->username = $value; 
    } 

    function getUrl(){ 
     return $this->url; 
    } 

    function setUrl($value){ 
     $this->url = $value; 
    } 

    function getTitle() 
    { 
     return $this->title; 
    } 

    function setTitle($value) { 

     $this->title = $value; 
    } 

    function getDescription() { 

    return $this->description; 
    } 

    function setDescription($value) 
    { 
     $this->description = $value; 
    } 

    function getPoints() 
    { 
     return $this->points; 
    } 

    function setPoints($value) 
    { 
     $this->points = $value; 
    } 

    function getRanking() 
    { 
     return $this->ranking; 
    } 

    function setRanking($value) 
    { 
     $this->ranking = $value; 
    } 

    function calculateRanking() 
    { 
     $created = $this->getCreated(); 

     $diff = $this->getTimeDifference($created, date('F d, Y h:i:s A')); 

     $time = $diff['days'] * 24; 
     $time += $diff['hours']; 
     $time += ($diff['minutes']/60); 
     $time += (($diff['seconds']/60)/60); 

     $base = $time + 2;   

     $this->ranking = ($this->points - 1)/pow($base, 1.5); 

     $this->save(); 
    } 

    function vote() 
    { 
     $this->points++; 
     $this->save(); 
    } 

    function getUrlDomain() 
    { 
     /* We extract the domain from the URL 
     * using the following regex pattern 
     */ 

     $url = $this->getUrl(); 
     $matches = array(); 
     if(preg_match('/http:\/\/(.+?)\//', $url, $matches)) 
     { 
      return $matches[1]; 
     } 
     else 
     { 
      return $url; 
     } 
    } 

    function getTimeDifference($start, $end) 
    { 
     $uts['start']  = strtotime($start); 
     $uts['end']  = strtotime($end); 
     if($uts['start']!==-1 && $uts['end']!==-1) 
     { 
      if($uts['end'] >= $uts['start']) 
      { 
       $diff = $uts['end'] - $uts['start']; 
       if($days=intval((floor($diff/86400)))) 
        $diff = $diff % 86400; 
       if($hours=intval((floor($diff/3600)))) 
        $diff = $diff % 3600; 
       if($minutes=intval((floor($diff/60)))) 
        $diff = $diff % 60; 
       $diff = intval($diff); 
       return(array('days'=>$days, 'hours'=>$hours, 'minutes'=>$minutes, 'seconds'=>$diff)); 
      } 
      else 
      { 
       echo("Ending date/time is earlier than the start date/time"); 
      } 
     } 
     else 
     { 
      echo("Invalid date/time data detected"); 
     } 
     return(false); 
    } 



    function getElapsedDateTime() 
    { 
     $db = null; 
     $record = null; 

     $record = Article::getById($this->id); 
     $created = $record->getCreated();   

     $diff = $this->getTimeDifference($created, date('F d, Y h:i:s A')); 
     //echo 'new date is '.date('F d, Y h:i:s A'); 
     //print_r($diff); 

     if($diff['days'] > 0) 
     { 
      return sprintf("hace %d dias", $diff['days']); 
     } 
     else if($diff['hours'] > 0) 
     { 
      return sprintf("hace %d horas", $diff['hours']); 
     } 
     else if($diff['minutes'] > 0) 
     { 
      return sprintf("hace %d minutos", $diff['minutes']); 
     } 
     else 
     { 
      return sprintf("hace %d segundos", $diff['seconds']); 
     } 
    } 

    function save() { 

    /* 
      Here we do either a create or 
      update operation depending 
      on the value of the id field. 
      Zero means create, non-zero 
      update 
    */ 

     if(!get_magic_quotes_gpc()) 
     { 
      $this->title = addslashes($this->title); 
      $this->description = addslashes($this->description); 
     } 

     try 
     { 
      $db = parent::getConnection(); 
      if($this->id == 0) 
      { 
       $query = 'insert into articles (modified, username, url, title, description, points)'; 
       $query .= " values ('$this->getModified()', '$this->username', '$this->url', '$this->title', '$this->description', $this->points)"; 
      } 
      else if($this->id != 0) 
      { 
       $query = "update articles set modified = NOW()".", username = '$this->username', url = '$this->url', title = '".$this->title."', description = '".$this->description."', points = $this->points, ranking = $this->ranking where id = $this->id"; 
      } 

      $lastid = parent::execSql2($query); 

      if($this->id == 0) 
       $this->id = $lastid; 

     } 
     catch(Exception $e){ 
      throw $e; 
     } 
    } 


    function delete() 
    { 
     try 
     { 
      $db = parent::getConnection(); 
      if($this->id != 0) 
      {    ; 
       /*$comments = $this->getAllComments(); 
       foreach($comments as $comment) 
       { 
        $comment->delete(); 
       }*/ 
       $this->deleteAllComments(); 
       $query = "delete from articles where id = $this->id"; 
      } 
      parent::execSql($query); 


     } 
     catch(Exception $e){ 
      throw $e; 
     } 
    } 

    static function getAll($conditions = ' ') 
    { 
     /* Retrieve all the records from the 
     * database according subject to 
     * conditions 
     */ 

     $db = null; 
     $results = null; 
     $records = array(); 
     $query = "select id, created, modified, username, url, title, description, points, ranking from articles $conditions"; 
     try 
     { 
      $db = parent::getConnection(); 

      $results = parent::execSql($query); 

      while($row = $results->fetch_assoc()) 
      { 
       $r_id = $row['id']; 
       $r_created = $row['created']; 
       $r_modified = $row['modified']; 

       $r_title = $row['title']; 
       $r_description = $row['description']; 

       if(!get_magic_quotes_gpc()) 
       { 
        $r_title = stripslashes($r_title); 
        $r_description = stripslashes($r_description); 
       } 

       $r_url = $row['url']; 
       $r_username = $row['username']; 
       $r_points = $row['points']; 
       $r_ranking = $row['ranking']; 

       $article = new Article($r_title, $r_description , $r_url, $r_username, $r_created, $r_modified); 
       $article->id = $r_id; 
       $article->points = $r_points; 
       $article->ranking = $r_ranking; 
       $records[] = $article; 
      } 
      parent::closeConnection($db); 
     } 
     catch(Exception $e) 
     { 
      throw $e; 
     } 

     return $records; 
    } 

    static function getById($id) 
    {/* 
    * Return one record from the database by its id */ 

     $db = null; 
     $record = null; 

     try 
     { 
      $db = parent::getConnection(); 
      $query = "select id, username, created, modified, title, url, description, points, ranking from articles where id = $id"; 
      $results = parent::execSQL($query); 
      if(!$results) { 
       throw new Exception ('Record not found', EX_RECORD_NOT_FOUND); 
      } 

      $row = $results->fetch_assoc(); 
      parent::closeConnection($db); 

      if(!get_magic_quotes_gpc()) 
      { 
       $row['title'] = stripslashes($row['title']); 
       $row['description'] = stripslashes($row['description']); 
      } 


      $article = new Article($row['title'], $row['description'], $row['url'], $row['username'], $row['created'], $row['modified']); 
      $article->id = $row['id']; 
      $article->points = $row['points']; 
      $article->ranking = $row['ranking']; 
      return $article; 

     } 
     catch (Exception $e){ 
      throw $e; 
     } 
    } 

    static function getNumberOfComments($id) 
    {/* 
    * Return one record from the database by its id */ 

     $db = null; 
     $record = null; 

     try 
     { 
      $db = parent::getConnection(); 
      $query = "select count(*) as 'total' from comments where article_id = $id"; 
      $results = parent::execSQL($query); 
      if(!$results) { 
       throw new Exception ('Comments Count Query Query Failed', EX_QUERY_FAILED); 
      } 

      $row = $results->fetch_assoc(); 
      $total = $row['total']; 
      parent::closeConnection($db);  

      return $total; 


     } 
     catch (Exception $e){ 
      throw $e; 
     } 
    } 

    function deleteAllComments() 
    {/* 
    * Return one record from the database by its id */ 

     $db = null; 
     try 
     { 
      $db = parent::getConnection(); 
      $query = "delete from comments where article_id = $this->id"; 
      $results = parent::execSQL($query); 
      if(!$results) { 
       throw new Exception ('Deletion Query Failed', EX_QUERY_FAILED); 
      } 
      parent::closeConnection($db); 
     } 
     catch (Exception $e){ 
      throw $e; 
     } 
    } 


    function getAllComments($conditions = ' ') 
    { 
     /* Retrieve all the records from the 
     * database according subject to 
     * conditions 
     */ 
     $conditions = "where article_id = $this->id"; 
     $comments = Comment::getAll($conditions); 
     return $comments; 
    } 


    static function getTestData($url) 
    { 
     $page = file_get_contents($url); 




    } 

} 
?> 

任何建议或意见表示赞赏,谢谢。

+3

在发布代码,它的大加赞赏。 – Ray 2009-02-17 22:51:07

回答

8

使例如另一个表user_votes与结构: USER_ID诠释不为空 article_id的诠释不是空 主键(USER_ID,article_id的)

在投票功能

首先尝试插入,如果插入是全成再增加$这 - >点

3

有一个表跟踪用户对文章的投票(类似于UserID,ArticleID,VoteTimeStamp)。然后,您可以在$article->vote();方法中进行检查,以确保当前登录的用户对该文章没有任何投票。如果你想保持快速的事情(所以你并不总是必须使用连接来获得投票计数),你可以有一个触发器(或自定义PHP代码),当添加/删除投票时更新总投票数数你目前保持在文章表中。

3

您有以下选择:

跟踪的谁投票的IP,并将其存储在数据库中。许多人可能会分享知识产权,这可能是不好的,但可以使用代理等手段绕过知识产权。

另一种解决方案是在浏览器中存储cookie。这可能比第一种解决方案好一点,因为它可以让来自同一知识产权的许多人投票。但是,由于您可以删除Cookie,因此也很容易规避。

最后也是唯一的安全方法是要求您的用户注册投票。通过这种方式,您可以将用户名和密码与投票结合起来,并且可以确保每个人只能投票一次,除非允许他们拥有多个用户。

最后的解决方案可能是前两个解决方案的组合,但它仍然是可以阻止的。

2

您可以拥有一个包含用户ID和文章ID的表格,名称与article_votes类似。因此,当用户x为文章y投票时,插入两个ID都是一行。这使您可以检查用户是否投了文章。

要计算的项目数,你可以使用这样的查询:如果您剪切代码下降到只有客户的相关SELECT COUNT(*) AS votes FROM article_votes WHERE article=[article id]