PHP / MYSQL разрешает только один голос за члена? - PullRequest
3 голосов
/ 15 сентября 2009

Я давал задание по настройке системы голосования за награды, я не слишком много знаю о php и mysql. Но я знаю об этом больше, чем кто-либо еще здесь, и мой босс в отпуске. Но я повторно использовал код, который ранее был оставлен в нашей системе, и адаптировал его на этот год.

В основном система голосования работает нормально, и я установил новые таблицы в mysql для сбора данных. Я обнаружил один довольно большой недостаток в существующем коде и не уверен, как его изменить. В основном код позволяет людям голосовать столько раз, сколько они хотят в данный момент. Я хочу ограничить это только одним голосом за члена, чтобы сохранить справедливость.

Итак, в данный момент участники входят в систему с номером участника, а затем голосуют. Голоса хранятся в таблицах mysql, и затем я могу сложить голоса, запросив данные.

Я надеялся, что кто-нибудь может помочь мне добавить одну или две строки кода, которые просто проверят, проголосовал ли уже участник. Когда участник голосует, его член нет. хранится в таблицах sql вместе с их выборами голосов. Поэтому, возможно, лучший способ - проверить, существует ли в таблице мемерид, и если да, то сказать пользователю, что он уже проголосовал, или слова на этот счет.

<?php
//Insert into volunteer awards
$coach=mysql_real_escape_string($_SESSION['coach']);
$official=mysql_real_escape_string($_SESSION['official']);
$young_volunteer=mysql_real_escape_string($_SESSION['young_volunteer']);
$volunteer=mysql_real_escape_string($_SESSION['volunteer']);

$memberid=$_SESSION['MM_Username'];
$association=$_SESSION['MM_Association'];
$region=$_SESSION['Region'];


$sql_query = mysql_query("INSERT INTO awards_2009_votes (`id`, `member_id`, `region`, `coach`, `official`, `volunteer`, `young_volunteer`) VALUES ('', '$memberid', '$region', '$coach', '$official', '$volunteer', '$young_volunteer')") or die (mysql_error());
?>

Спасибо

Ответы [ 4 ]

8 голосов
/ 15 сентября 2009

Вы можете добавить УНИКАЛЬНОЕ ограничение к вашей таблице. Это однократная операция - вам не нужно делать это каждый раз, когда запускается ваш скрипт, это изменение структуры таблицы. Запустите это в своем инструменте администрирования MySQL (например, phpMyAdmin, Navicat, HeidiSQL, что-у-вас):

ALTER TABLE awards_2009_votes ADD UNIQUE (member_id);

После этого изменения будет невозможно добавить второй голос с тем же идентификатором участника - ВСТАВИТЬ (или ОБНОВИТЬ) не удастся.

Преимущество здесь в том, что проверка выполняется автоматически в базе данных, поэтому вам не нужно беспокоиться о 1) проверке дубликатов с помощью вашего кода или 2) о добавлении нескольких голосов вручную.


Как говорит @ middaparka , вы должны использовать INSERT IGNORE, чтобы избежать ошибки «дубликата ключа»:

$sql_query = mysql_query("INSERT IGNORE INTO awards_2009_votes (`member_id`, `region`, `coach`, `official`, `volunteer`, `young_volunteer`) VALUES ('$memberid', '$region', '$coach', '$official', '$volunteer', '$young_volunteer')") or die (mysql_error());
if (mysql_insert_id()) {
    // row was inserted - vote added
} else {
    // row was not inserted - already voted
}
3 голосов
/ 15 сентября 2009

Из вашего кода я не уверен, какова структура вашей таблицы, но следующая структура таблицы ограничит голосование пользователей одним голосом по теме:

Таблица пользователей

user_id int unsigned not null auto_increment,
username varchar
// and other user info fields

Таблица тем

topic_id int unsigned not null auto_increment,
topic_title varchar
// and other topic info fields

Стол для голосования

user_id,
topic_id,
vote_value,
primary key (user_id,topic_id) //this is the constraint that will allow only one vote
1 голос
/ 15 сентября 2009

Вот быстрый и грязный подход:

$sql_query = "SELECT FROM awards_2009_votes WHERE member_id = '$memberid'";
$sql_result = mysql_query($sql_query);
$num_rows = mysql_num_rows($sql_result);

if ($num_rows > 0) {
    // this member has already voted
} else {
    // carry on
}

Как указал Писквор, это решение имеет (как минимум) два ограничения:

  1. Он ограничен методом, в котором он содержится, поэтому он не запрещает множественные голоса в целом - только с помощью этого конкретного метода. (Вы можете написать функцию, содержащую эту же проверку, но вам все равно придется вызывать эту функцию везде, где пользователь пытается проголосовать.)
  2. Это приводит к дополнительной нагрузке на базу данных, что может быть неприемлемо в сценарии с большим трафиком.

Учитывая эти моменты, я рекомендую сначала запустить скрипт, чтобы проверить наличие повторяющихся значений member_id в вашей таблице голосов, удалить все, кроме одного, в каждом случае, а затем добавить ограничение UNIQUE в вашу таблицу. Оттуда вы можете быть уверены, что в вашей таблице никогда не будет более одной строки с одинаковым member_id.

0 голосов
/ 15 сентября 2009

Вы можете написать несколько строк следующим образом, хотя я не проверял это, но они должны работать ...

$result=mysql_query("select count(*) count from awards_2009_votes where member_id='$memberid'");

$has_voted_array=mysql_fetch_array($result);
if($has_voted['count']!=0)
echo "You have already registered youur vote";
else
{
//do normal operation
$sql_query = mysql_query("INSERT INTO awards_2009_votes (id, member_id, region, coach, official, volunteer, young_volunteer) VALUES ('', '$memberid', '$region', '$coach', '$official', '$volunteer', '$young_volunteer')") or die (mysql_error());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...