私が変更しようとしているphp/mysqlポーリングがあります。PHP/MySQLの投票 - IPに基づいて繰り返される投票はありません
投票した場合は一意のクッキーを設定し、クッキーが設定されている場合は同じ投票で2回投票しないようにします。それが設定されている場合は、結果のみが表示されます。
私のやりたいことは、自分のIPがデータベースにもある場合、ユーザーが複数回投票するのをブロックすることです。
私はIPを取得してデータベースに格納することができましたが、それがデータベースにあるかどうかを判断するロジックを理解できません。
誰かが私を正しい方向に向けることができますか?
クッキーの検出はコンストラクタと投票メソッドにあります。 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;'> </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>
ありがとうございました。私はこれを試し、後でまた報告します。 –
それはトリックでした。ありがとう。 –