gpt4 book ai didi

PHP/MySQL 投票 - 不重复基于 IP 的投票

转载 作者:行者123 更新时间:2023-11-30 23:32:32 26 4
gpt4 key购买 nike

我有一个正在尝试修改的 php/mysql 轮询。

如果您已经投票,它会设置一个唯一的 cookie,如果设置了 cookie,它会阻止您在同一个民意调查中投票两次。如果已设置,则您只能看到结果。

我想做的是阻止用户多次投票,如果他们的 IP 也在数据库中(我知道 session 会更好,但对我的情况来说不可能)。

我已经设法获取 IP 并将其存储在数据库中,但我无法弄清楚告诉轮询它是否在数据库中的逻辑。

有人能指出我正确的方向吗?

cookie 检测在构造函数和投票方法中。 cookie 在投票方法的末尾设置。

    <?php
# don't display errors
ini_set('display_errors',0);
error_reporting(E_ALL|E_STRICT);

class webPoll {

# makes some things more readable later
const POLL = true;
const VOTES = false;

# number of pixels for 1% on display bars
public $scale = 2;
public $question = '';
public $answers = array();

private $header = '<form class="webPoll" method="post" action="%src%">
<input type="hidden" name="QID" value="%qid%"/>
<h4>%question%</h4>
<fieldset><ul>';
private $center = '';
private $footer = "\n</ul></fieldset>%button%\n%totalvotes%\n</form>\n";
private $button = '<p class="buttons"><button type="submit" class="vote">Vote!</button></p>';
private $totalvotes = '';
private $md5 = '';
private $id = '';

/**
* ---
* Takes an array containing the question and list of answers as an
* argument. Creates the HTML for either the poll or the results depending
* on if the user has already voted
*/
public function __construct($params) {
$this->id = array_shift($params);
$this->question = array_shift($params);
$this->answers = $params;
$this->md5 = md5($this->id);
$this->header = str_replace('%src%', $_SERVER['SCRIPT_NAME'], $this->header);
$this->header = str_replace('%qid%', $this->md5, $this->header);
$this->header = str_replace('%question%', $this->question, $this->header);

# seperate cookie for each individual poll (has the user voted yet?)
# if cookie is set then show results(VOTES), if not then let user vote(POLL)
isset($_COOKIE[$this->md5]) ? $this->poll(self::VOTES) : $this->poll(self::POLL);
}
private function poll($show_poll) {
$replace_btn = $show_poll ? $this->button : '';
$get_results = webPoll::getData($this->md5);
$total_votes = array_sum($get_results);
$replace_votes = $show_poll ? $this->totalvotes : '<small>Total Votes: '.$total_votes.'</small>';

$this->footer = str_replace('%button%', $replace_btn, $this->footer);
$this->footer = str_replace('%totalvotes%', $replace_votes, $this->footer);

# static function doesn't have access to instance variable
if(!$show_poll) {
$results = webPoll::getData($this->md5);
$votes = array_sum($results);
}

for( $x=0; $x<count($this->answers); $x++ ) {
$this->center .= $show_poll ? $this->pollLine($x) : $this->voteLine($this->answers[$x],$results[$x],$votes);
}
echo $this->header, $this->center, $this->footer;
}
private function pollLine($x) {
isset($this->answers[$x+1]) ? $class = 'bordered' : $class = '';
return "
<li class='$class'>
<label class='poll_active'>
<input type='radio' name='AID' value='$x' />
{$this->answers[$x]}
</label>
</li>
";
}
private function voteLine($answer,$result,$votes) {
$result = isset($result) ? $result : 0;
$percent = round(($result/$votes)*100);
$width = $percent * $this->scale;
return "
<li>
<div class='result' style='width:{$width}px;'>&nbsp;</div>{$percent}%
<label class='poll_results'>
$answer
</label>
</li>
";
}
/**
* processes incoming votes. votes are identified in the database by a combination
* of the question's MD5 hash, and the answer # ( an int 0 or greater ).
*/
static function vote() {

if(!isset($_POST['QID']) || !isset($_POST['AID']) || isset($_COOKIE[$_POST['QID']])) {
# leave vote method if any of the above are true
return;
}

$dbh = new PDO('mysql:host=????;dbname=????', '????', '');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

try {
# add vote info to 'tally' table
$sth = $dbh->prepare("INSERT INTO tally (QID,AID,votes,created_at) values (?, ?, 1, NOW())");
$ex = array($_POST['QID'],$_POST['AID']);
$sth->execute($ex);
# add ip info to 'ips' table
$sth2 = $dbh->prepare("INSERT INTO ips (ips,QID,AID) values (?,?,?)");
$ex2 = array($_SERVER['REMOTE_ADDR'],$_POST['QID'],$_POST['AID']);
$sth2->execute($ex2);
}
catch(PDOException $e) {
# 23000 error code means the key already exists, so UPDATE!
if($e->getCode() == 23000) {
try {
# update number of votes for answers in 'tally' table
$sth = $dbh->prepare("UPDATE tally SET votes = votes+1 WHERE QID=? AND AID=?");
$sth->execute(array($_POST['QID'],$_POST['AID']));
# add ip info to 'ips' table
$sth2 = $dbh->prepare("INSERT INTO ips (ips,QID,AID) values (?,?,?)");
$ex2 = array($_SERVER['REMOTE_ADDR'],$_POST['QID'],$_POST['AID']);
$sth2->execute($ex2);
}
catch(PDOException $e) {
webPoll::db_error($e->getMessage());
}
}
else {
webPoll::db_error($e->getMessage());
}
}

# entry in $_COOKIE to signify the user has voted, if he has
if($sth->rowCount() == 1) {
setcookie($_POST['QID'], 1, time()+60*60*24*365, '/', '', FALSE, TRUE);
$_COOKIE[$_POST['QID']] = 1;
}
}
static function getData($question_id) {
try {
$dbh = new PDO('mysql:host=????;dbname=????', '????', '');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$STH = $dbh->prepare('SELECT AID, votes FROM tally WHERE QID = ?');
$STH->execute(array($question_id));
}
catch(PDOException $e) {
# Error getting data, just send empty data set
return array(0);
}

while($row = $STH->fetch()) {
$results[$row['AID']] = $row['votes'];
}

return $results;
}
/*
* You can do something with the error message if you like. Email yourself
* so you know something happened, or make an entry in a log
*/
static function db_error($error) {
echo "A database error has occurred. $error";
exit;
}

}
?>

下面是民意调查的实现方式:

    <?php
ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);

include('webPoll-hiddenMD5.class.php');
webPoll::vote();
?>
<html>
<head>
<title>Poll Test</title>
<link rel="stylesheet" href="poll.css" type="text/css" />
<!--[if IE]>
<style> body { behavior: url("res/hover.htc"); } </style>
<![endif]-->
</head>
<body>
<?php

$a1 = new webPoll(array(
'March 16, 2012 What subjects would you like to learn more about?',
'What subjects would you like to learn more about?',
'HTML & CSS',
'Javascript',
'JS Frameworks (Jquery, etc)',
'Ruby/Ruby on Rails',
'PHP',
'mySQL'));

?>
</body>
</html>

最佳答案

看起来好像所有的逻辑都在构造函数中,只需针对用户 ip 和 qid 查询 ip 表,看看结果数是否大于 0。如果是,则只需更改最后一行构造函数 isset($_COOKIE[$this->md5] || count($res)>0 ) ? $this->poll(self::VOTES) : $this->poll(self::POLL);

关于PHP/MySQL 投票 - 不重复基于 IP 的投票,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9841352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com