我正在使用本教程向网站添加简易民意调查:http://code.tutsplus.com/articles/creating-a-web-poll-with-php--net-14257
我已修改此代码,因此我可以通过输入轮询标题和存储在数据库表中的问题来创建自己的民意调查。然后查询该表并从数据库加载轮询。这工作正常,但是,当我试图返回每个问题的投票数时,每次返回值为0。表'tally'包含问题ID,答案ID和投票数。
当我尝试从webPoll类向此计数表中插入数据时,QID和AID行都是空白的,每次只有投票值递增。
我的数据库是MySQL,我遵循的教程是将数据插入到SQLite数据库中,我认为这可能是问题,但我现在似乎无法找到解决方案。
总之,我需要在webPoll类中插入QID,AID和amp;投票值为QID和AID未插入。
帐簿
CREATE TABLE tally (
QID varchar(32) NOT NULL,
AID integer NOT NULL,
votes integer NOT NULL,
PRIMARY KEY (QID,AID))
webPoll类
$mysql_host = "localhost";
$mysql_database = "vote";
$mysql_user = "root";
$mysql_password = "";
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</form>\n";
private $button = '<p class="buttons"><button type="submit" class="vote">Vote!</button></p>';
private $md5 = '';
/**
* ---
* 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->question = array_shift($params);
$this->answers = $params;
$this->md5 = md5($this->question);
$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
isset($_COOKIE[$this->md5]) ? $this->poll(self::VOTES) : $this- >poll(self::POLL);
}
private function poll($show_poll) {
$replace = $show_poll ? $this->button : '';
$this->footer = str_replace('%button%', $replace, $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']])) {
return;
}
try{
$dbh = new PDO('mysql:host=localhost;dbname=vote', 'root', '');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
} catch(PDOException $e) {
echo "Error: " . $e->getMessage() . "<br/>";
}
try {
$sth = $dbh->prepare("INSERT INTO tally (QID,AID,votes) values ('QID', 'AID', '1')" );
$sth->execute(array($_POST['QID'],$_POST['AID']));
}
catch(PDOException $e) {
# 23000 error code means the key already exists, so UPDATE!
if($e->getCode() == 23000) {
try {
$sth = $dbh->prepare("UPDATE tally SET votes = votes + 1 WHERE QID='$QID' AND AID='$AID'");
$sth->execute(array($_POST['QID'],$_POST['AID']));
}
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);
$_COOKIE[$_POST['QID']] = 1;
}
}
static function getData($question_id) {
try {
$dbh = new PDO('mysql:host=localhost;dbname=vote', 'root', '');
$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
webPoll::db_error($e->getMessage());
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 occured. $error";
exit;
}
}
答案 0 :(得分:0)
您正在错误地使用预准备语句。在values
内你应该有占位符。 execute
中的值绑定到这些占位符。
所以:
$sth = $dbh->prepare("INSERT INTO tally (QID,AID,votes) values ('QID', 'AID', '1')" );
正在向您的数据库发送QID
和AID
。如果这些是整数列,我怀疑你会取代0
代替它们。
您应该将其更改为:
$sth = $dbh->prepare("INSERT INTO tally (QID,AID,votes) values (?, ?', '1')" );
您的execute
:
$sth->execute(array($_POST['QID'],$_POST['AID']));
已正确设置以将两个值传递给占位符。
您还需要进一步修复另一个update
。
$sth = $dbh->prepare("UPDATE tally SET votes = votes + 1 WHERE QID=? AND AID= ?");
准备好的陈述应该很少有变量,如果它们在那里,它们应该根据允许的术语列入白名单。
您可以阅读有关准备好的陈述的更多信息:
http://php.net/manual/en/pdo.prepared-statements.php
https://en.wikipedia.org/wiki/Prepared_statement