Некорректно работает запрос в БД

Yan

Новичок
Добрый день!
Делаю голосование на сайте. Для этого id проголосовавшего вношу в таблицу и проверяю есть ли оно там или нет, для того, чтобы разрешить голосование или нет.
Делаю в ООП. Вот код:
Создаю объект и вызываю метод:
Код:
$vaca=new Vote(0, $player, 0,0,0);
$vaca->insert_quantity();
Сам метод ($this->player это id пользователя, который хранится в переменной $player):
Код:
function insert_quantity(){
    Create::connect();
    $sel=mysql_query('SELECT * FROM quantity WHERE id_player='.$this->player);
    $c=mysql_num_rows($sel);
    if($c>0){
        echo 'Вы не можете проголосовать больше 1 раза <br>';
    }else{
        mysql_query('INSERT INTO quantity (id_player) VALUES ('.$this->player.')');
        if(mysql_error()){
            echo mysql_error().'<br>';
        }
        echo 'Ok';
    }
}
Проблема в том, что если в таблице "quantity" НЕТ записи с этим пользователем, то она создается, что и должно быть, но на экран выводится тут же сообщение 'Вы не можете проголосовать больше 1 раза', т.е. каким-то образом код не доходит до echo 'Ok', а снова начинается сверху, соответственно уже находит эту строку и выводит эту надпись.
Если же удалить INSERT запрос, а оставить только echo 'Ok', то при отсутствии записи, на экран выводится надпись 'Ok', что и должно быть.
Циклов никаких тут не использую, этот метод больше нигде не вызываю, объекта такого больше нигде нет. Я просидел с этим уже часов 5, помочь никто не может.
Код элементарный, но не работает как надо. Буду очень благодарен за помощь!
 

AnrDaemon

Продвинутый новичок
1. Должен вас разочаровать, это не ООП.
2. У вас логика работы функции убогая. Впрочем, вы и сами на это указываете в вашем посте.
Переписывайте код.
 

Yan

Новичок
1. Должен вас разочаровать, это не ООП.
2. У вас логика работы функции убогая. Впрочем, вы и сами на это указываете в вашем посте.
Переписывайте код.
Согласен, я новичек, еще учусь, вот разбил на 2 метода, конструкцию if вынес из метода, так, наверное, будет правильнее? Несмотря на то, что стало 2 метода, создаю два разных объекта для вызова каждого из методов, но результат тот же.

Файл с объектами:

Код:
$player=$_COOKIE['id'];
$player=(integer) $player;

$vaca=new Vote(0, $player, 0,0,0);
$vaca->select_quantity();
$count=$vaca->count;

echo $count;
echo '<br>';

if($count==0){
    $cad=new Vote(0, $player, 0,0,0);
    $cad->insert_quantity();
}
Файл с классом:
Код:
function select_quantity(){
    Create::connect();
    $sel=mysql_query('SELECT * FROM quantity WHERE id_player='.$this->player);
    if(mysql_error()){
        echo mysql_error().'<br>';
    }
    $this->count=mysql_num_rows($sel);;
}

function insert_quantity(){
    Create::connect();
    mysql_query('INSERT INTO quantity (id_player) VALUES ('.$this->player.')');
    if(mysql_error()){
        echo mysql_error().'<br>';
    }
    echo 'Ok';  
}
Там, где я вывожу количество строк (echo $count), то пишет 1 вместо 0, т.е. вывод отсутствия строк просто игнорируется, это для меня вообще загадка, ведь это уже происходит вне класса в другом файле, а работает точно так же.
 

AnrDaemon

Продвинутый новичок
Правильнее будет вносить не проверяя.
Если БД выдаст ошибку, значит, товарищ уже голосовал и ему надо об этом сообщить.
 

AnrDaemon

Продвинутый новичок
С какого перепугу?… БД исправляйте, раз у вас структура таблиц кривая и позволяет голосовать дважды.
 

Yan

Новичок
С какого перепугу?… БД исправляйте, раз у вас структура таблиц кривая и позволяет голосовать дважды.
Что-то не пойму, а какая может быть структура, чтобы не добавлялась новая строка, если значения всех полей, кроме автоинкремента id, совпадают? Это можно реализовать в самой таблице?

Но все равно так и не ясно почему этот код настолько неправильно работает, у меня есть почти такие же методы, которые нормально работают, неужели тут где-то настолько нарушена логика действий, а я этого не вижу?
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Что-то не пойму, а какая может быть структура,
Нормальная!
чтобы не добавлялась новая строка, если значения всех полей, кроме автоинкремента id, совпадают?
Бредовая постановка задачи ведёт к бредовым решениям.
Исправляйте формат таблицы. А перед тем - правильно формулируйте задачу.

Это можно реализовать в самой таблице?
Да! В таблице может быть больше одного уникального индекса! Сюрприз, правда?…

Но все равно так и не ясно почему этот код настолько неправильно работает, у меня есть почти такие же методы, которые нормально работают, неужели тут где-то настолько нарушена логика действий, а я этого не вижу?
Потому что он в принципе неверен… Никто так не делает, чтобы не получить race condition.
Если субъект одновременно попытается проголосовать два раза - ты его и зарегистрируешь два раза.
Потому что оба раза ты проверишь, что записи нет, и оба раза добавишь новую запись.
 

Yan

Новичок
Да! В таблице может быть больше одного уникального индекса! Сюрприз, правда?…
Вы не поняли что я имею ввиду. Естественно, что там все id уникальны, я имел ввиду есть ли возможность в БД сделать так, что не создавать новую строку, если в таблице уже существует строка со значениями полей такими же, как и в той, которую хотим создать новую?
Я такого не знаю, поэтому и применил if.


Если субъект одновременно попытается проголосовать два раза - ты его и зарегистрируешь два раза.
Потому что оба раза ты проверишь, что записи нет, и оба раза добавишь новую запись.
У меня проблема возникает когда субъект пытается проголосовать самый первый раз, полностью неверно идет алгоритм, я описал проблему в самом первом сообщении.
Когда он кликает на кнопку, я передаю еще массив данных через ajax на другой файл, в котором и создаю объекты класса. Может эта проблема как-то связана с применением ajax?
 

AnrDaemon

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

Yan

Новичок
Да плевать, когда у вас проблема возникает. Я вам принципиальную ошибку вашего подхода объясняю.
У вас между проверкой, не голосовал ли клиент, и собственно голосованием может произойти что угодно.
Я так и не понял ошибку свою. А понял лишь, что структура таблицы у меня неправильная, а должна быть "Нормальная", на этом все.
Если вы знаете как решить эту проблему, буду рад помощи.
 

AnrDaemon

Продвинутый новичок
Я два раза сказал, как решить проблему.
1. Поставить правильно задачу. Как должно проходить голосование? Одно ли это голосование? Как идентифицируются участники голосования? Можно ли одному участнику голосовать дважды, трижды в одном голосовании?
Из этого получаем набор информации (количество и назначение полей), необходимый для сохранения в БД.
2. Правильно закодировать решение. Тривиально.
 

Yan

Новичок
Я два раза сказал, как решить проблему.
1. Поставить правильно задачу. Как должно проходить голосование? Одно ли это голосование? Как идентифицируются участники голосования? Можно ли одному участнику голосовать дважды, трижды в одном голосовании?
Из этого получаем набор информации (количество и назначение полей), необходимый для сохранения в БД.
Голосование проходит так:
Админ кликает на кнопку, открывая голосование, я в маленькую таблицу "А" вношу в одно поле 1, что значит, что голосование открыто.
Юзер может голосовать только один раз, результатом его голосования будет массив данных, полученный путем JS, который я передаю через аякс.
Если он НЕ голосовал, то в маленькую таблицу "Б" хочу внести его id, что значит, что он уже проголосовал.
После внесения его id в таблицу "Б", я раскладываю массив данных, который с ним пришел, в таблицу "В".
Если юзер уже голосовал, то я и хочу сделать проверку на то, хранится ли в таблице "Б" его id, что значило бы, что ему уже нельзя голосовать и новый массив, который он притащил с собой, уже не надо вносить в таблицу "В".
После того, как юзеры, которые хотели проголосовать, проголосовали, админ кликает на другую кнопку, закрывая голосование, а в ту же маленькую таблицу "А" вносится уже 0, что значит, что голосование закрыто.
На странице голосования у юзеров сделаю проверку на то, какая цифра находится в таблице "А", 0 или 1, соответственно дать возможность юзеру голосовать или не дать. Также после этого хочу сделать полную очистку таблицы "Б", чтобы она стала пустая и ничего не спуталось со следующим голосованием.
Итого:
В таблице "А" только одно поле, значение которого будет меняться на 0 или на 1.
В таблице "Б" только одно поле, значение которого-это id юзеров, которые уже проголосовали.
В таблице "В" несколько полей, но то уже неважно, там хранятся данные, полученные из массивов, которые юзеры выбрали.
 

AnrDaemon

Продвинутый новичок
А теперь перечитайте всё, что вы написали.
Я вижу минимум три противоречия.
 

Yan

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

AnrDaemon

Продвинутый новичок
Отвлекитесь от запросов уже.
Просто прочитайте то, что вы написали.
 

AnrDaemon

Продвинутый новичок
У вас так плохо с родным языком?…
1.
Если он НЕ голосовал, то в маленькую таблицу "Б" хочу внести его id, что значит, что он уже проголосовал.
2.
я раскладываю массив данных, который с ним пришел, в таблицу "В".
На…ээээ…зачем? Даже не так, какое вам нафиг дело до того, что там от юзера пришло? Все данные по пользователям у вас есть в локальной БД.
3. Что там админ кликает, никому не интересно. Вопрос был конкретно про процесс самого голосования.
4. Нахрена две таблицы?…
 

Yan

Новичок
1. Что вас смутило? Использование perfect вместо continuous? Замените слово "уже" на словосочетание "только что".
2. Этот массив строится на основе сортируемого (sortable) списка, который юзер "сделал", этот массив не относится к его данным, из данных юзера мне нужно лишь его id, который сохранился в куки при его авторизации.
3. Вы попросили объяснить как проходит голосование, я просто объяснил подробнее для полной картины.
4. Одна таблица только для админа, там он открывает/закрывает голосование кликом, соответственно в таблицу вносится 1 или 0. Я это хочу сделать для того, чтобы сайт понимал давать доступ юзерам к голосованию или нет, просто отправлять короткий запрос к таблице и извлекать это число (1 или 0). Мне это показалось очевидным, хотя понимаю, что на практике может обычно не так делается.
Вторая таблица уже для всех юзеров, id которых хранится в этой таблице для проверки на то, проголосовал ли конкретный пользователь. Данные в этой таблице временные.
 

AnrDaemon

Продвинутый новичок
Да, я попросил описать, как происходит голосование.
А не как оно начинается или завершается.
В связи с вышесказанным, меня не интересует таблица управления голосованием.
Повторяю вопрос - нафига две таблицы?…
 
Сверху