За последние 24 часа нас посетили 20086 программистов и 1661 робот. Сейчас ищут 1777 программистов ...

Как написать на php ежечасную акцию

Тема в разделе "Сделайте за меня", создана пользователем antonio21, 22 авг 2016.

  1. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Есть интернет-магазин, на котором настроена авторизация, то есть каждому зарегистрированному пользователю присваивается свой уникальный айди, а так же выдаются балы за покупку. И есть задача каждый час разыгрывать призы, сейчас это балы которые можно обменять на фирменные футболки.

    То есть, задача такая: начинаем раунд который длится один час ( собираем id всех кто кликнул на кнопку "участвовать" за этот час и списываем с каждого участника по 1 балу, выводим реал тайм кол-во участников и сколько времени до завершения раунда) после завершения часа, рандомайзером выбираем случайный id и начисляем ему кол-во балов которое равно кол-ву участников этого раунда, выводим сообщение о победе. После, все по новой.

    Прошу помочь или подсказать как это реализовать?!
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Ну можно сделать таблицу, id user_id, date_time, winner(false/true)
    По datetime мы сможем выборку по часам делать.
    Настраиваем cron на раз в час, например каждые 59 минут и 55 секунд запускаться,
    он будет запускать простой скрипт, делать выборку из таблицы с участниками, запрос фильтруем по date_time, например если сейчас 23.08.2016 8:59, то
    ищем где date_time > 23.08.2016 8:00:00 и date_time < 23.08.2016 8:59:59 и можно там сразу в SQL random добавить и подучить 1 запись победителя,
    делаем ему update winner = true.

    Это часть розыгрыша.
    Мало кто для магазина будет делать на халяву готовый код.
     
    antonio21 нравится это.
  3. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Да, начну с таблиц.

    Это благотворительный магазин, все деньги идут в фонд милосердие +рандомный розыгрыш футболок "Милосердие".
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    @antonio21 спрашивай если что-то будет не понятно
     
    antonio21 нравится это.
  5. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Думаю все-таки вывести в отдельную таблицу, например: «konkurs»

    И сделать там 24 строки и следующие колонки:

    [id], [№1-24_conkursa( их будет по кол-ву часов в дне)], [open/close], [date_close], [quantity of participants]

    1,7,12 1 1 11:59:55 3

    2,9,47 2 0 12:59:55 0



    Нажимаем на кнопку «участвовать», то есть: пишем в таблицу «konkurs» ( в строку которая открыта [open/close] имеет «1») id user(а) и +1 в [quantity of participants]



    В 11:59:56 кроном обновляю —> отправляю в рандомайзер список айди—> присваиваю [open/close] «0» и присваиваю [open/close] »1» следующей строке в таблице «konkurs», вывожу id победителя и [quantity of participants], перечисляю приз.



    Прошу посоветовать верно ли я думаю, я вижу себе это как-то так, но не уверен что это верно.
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Вроде логично, нужно проверить этот алгорит
     
    antonio21 нравится это.
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    таблица участников конкурса. айдишник пользователя, учетный период, признак победителя. нажимая участвовать пользователь заносит в базу айдиншник, час и ноль. кроном в начале следующего часа выбирается таблица участников за час предыдущий, рандомизируется, кому-нибудь записывается единица в победители.
     
    antonio21 и denis01 нравится это.
  8. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Создал две таблицы:
    konkurs
    `id_konkurs`,`id_users`,`open`,`last`,`quantity user`

    И

    users
    `id`,`login`,`win`,`balance`

    Думаю отказаться от привязки ко времени и не писать его в бд, а вызывать кроном каждые (55 минут, для удобства теста каждые 55 секунд)
    Что-то типо этого (я только учусь и прошу подсказать где я бред написал и помочь исправить, спасибо за понимание!):

    1. Закрываем предыдущий конкурс (если open=1 открыт, open=0 конкурс закрыт):
    И ставим "1" конкурсу который был последним в бд, в поле `last` чтобы было легче.
    PHP:
    1. <?php
    2. $update = "UPDATE `konkurs` SET `open` = '0' WHERE `open` = '1';)  //закрываем предыдущий конкурс (если open=1 открыт, open=0 конкурс закрыт)
    3.  
    4. $sql = "INSERT INTO `konkurs` (`last`) VALUES (1)";  //ставим "1" конкурсу который был последним в бд, в поле `last`.
    5.  
    6. $sql = "SELECT `id_users` FROM `id_konkurs` WHERE `last` ='1';  //выбираем все id последнего конкурса чтобы отпр. в рандомайзер
    7.  
    8. $winner = "INSERT INTO `konkurs` (`winner`) VALUES (id_user)"; //вписываем в бд id_user который победил
    9.  
    10. $sql = "INSERT INTO `users` (`win`) WHERE (id_user = $id_user) VALUES (1)"; //присваеваем победу.
    11.  
    12. $sql = "INSERT INTO `users` (`balance`) WHERE (id_user = $id_user) VALUES (+1)"; прибавляем победителю +1
    13. ?>
    2. Пишем в бд новый id конкурса прибавляя к нему +1 и пишем в бд что у этого "id_konkurs" open=1:
    PHP:
    1. <?php
    2. $sql = "INSERT INTO `konkurs` (`id_konkurs`, `open`) VALUES (NULL, 1)";
    3. ?>
    3. запускаем таймер обратного отсчета. только визуалка, функционала в нем нет.


    4. Пишем функционал кнопки "Участвовать"
    PHP:
    1. if(isset($_POST['submit'])) {   //если была нажата кнопка
    2.  
    3. if($errors['balance'] == '0' || < "1") // и баланс больше 0, то записываем id участника в таблицу konkurs.
    4.  
    5. $errors['id_user'] = checkLogin($fields['id_user']) === true ? '' : checkLogin($fields['id_user']); //и этот id еще не участвует
    6.  
    7. $sql = "INSERT INTO `konkurs` (`id_konkurs`) WHERE `open` = '1' VALUES ($id_user) // то записываем id участника в таблицу konkurs.
    8.  
    9. $sql = "INSERT INTO `konkurs` (`[quantity user]`) VALUES (+1) //пишем +1 к кол-ву участников
    10.  
    11. $sql = "UPDATE `users` SET `balance` - '1'; //списываем с юзера -1 бал.
     
    #8 antonio21, 24 авг 2016
    Последнее редактирование модератором: 24 авг 2016
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Профит такой архитектуры в чем?
     
    antonio21 нравится это.
  10. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Зато своё :)
     
    antonio21 нравится это.
  11. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @denis01, ну своё это не повод не использовать немного более грамотные решения)))) Хотелось бы чтоб автор сам расписал преимущества такого решения с несколькими таблицами, вместо использования одной таблицы участников конкурса. Например, зачем лишняя таблица конкурсов, если они по условиям задачи между собой отличаются только часом проведения?
     
  12. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Да, это вариант
     
    antonio21 нравится это.
  13. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Не совсем понял вопрос, таблица user уже есть, она для того чтобы в нее писать инфу о пользователе: `id`,`login`,`win`,`balance`

    А в таблицу konkurs пишется вся инфа по конкурсу: `id_konkurs`,`id_users`,`open`,`last`,`quantity user`

    Ваше решение я считаю более правильное, но как его реализовать пока не понимаю:

    таблица участников конкурса. айдишник пользователя, учетный период, признак победителя. нажимая участвовать пользователь заносит в базу айдиншник, час и ноль. кроном в начале следующего часа выбирается таблица участников за час предыдущий, рандомизируется, кому-нибудь записывается единица в победители.
    --- Добавлено ---
    И + нужно обновлять инфу о кол-ве участников, выводить таймер и закрывать раунд так сказать как время выйдет, а если ajax+php+mysql? :

    timer.php

    PHP:
    1. <?php
    2. if(!$_SESSION['t']){
    3.     $_SESSION['t']=3600; //1 час
    4. }else {
    5.     echo --$_SESSION['t'];
    6. }
    7. ?>

    script.js
    Код (Javascript):
    1. function ajax_timer(){
    2.         $.ajax({
    3.             type:"POST",
    4.             url :"timer.php",
    5.             data:{"s":1},
    6.             success:function(data){
    7.                 $("#s").empty();
    8.                 $("#s").html(data);
    9.                 if(data==0){ //если таймер равен 0
    10.                     clearInterval(c); //завершаем таймер
    11.                     //объявляем победителя, как это сделать?
    12.                 }
    13.             }
    14.        });
    15.     }
    16. var c = setInterval(ajax_timer,1000);
     
    #13 antonio21, 24 авг 2016
    Последнее редактирование модератором: 24 авг 2016
  14. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    и в чем проблема-то? кол-во участников можно дернуть из мускула, сгруппировав по часу проведения акции. и так кстати можно по всем акциям статистику выводить. а можно при добавлении юзера в акцию делать инкремент в каком-нибудь редисе чтоб базу лишний раз не дергать группировками. тогда вывод кол-ва участников текущей акции сведется к простому чтению ключа из редиса.
    таймер? ну ты когда создаешь страницу - у тебя есть время создания этой страницы. от этого времени акция еще будет длится ровно столько секунд, сколько до следующего часа. причем поскольку существуют полусдвинутые часовые пояса - то лучше точной отсчета брать именно время сервера а не клиента. ну а на клиенте уже жаваскриптом это значение оживлять и уменьшать ежесекундно.
    то есть по сути таблица конкурсов при данной формулировке задачи - вообще не нужна. ты абсолютно всю инфу можешь получать из юзеров и участников конкурса.

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

    жмакание на кнопке:
    дернули единицу из участников где час сейчас а юзер вот этот
    строка есть? ну ты мудила уже участвуешь! блокируем повторный ввод
    строки нет? смотрим баланс.
    денег нет? увы и ой.
    денег есть - списали одну уе и тут же вставили строку в участников.

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

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

    и всё это лишь одной таблицей. фантастика.
    зы. вторую таблицу (конкурсы) имеет смысл заводить если к статистике нужен очень частый доступ. тогда основные данные - победитель, сумма (а она же и кол-во участников) - можно будет "закэшировать" в этой таблице. остальные - как всегда не легко доступны из таблицы участников.
     
  15. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    а как это сделать? : кол-во участников можно дернуть из мускула, сгруппировав по часу проведения акции. и так кстати можно по всем акциям статистику выводить. а можно при добавлении юзера в акцию делать инкремент в каком-нибудь редисе чтоб базу лишний раз не дергать группировками. тогда вывод кол-ва участников текущей акции сведется к простому чтению ключа из редиса.
    таймер? ну ты когда создаешь страницу - у тебя есть время создания этой страницы. от этого времени акция еще будет длится ровно столько секунд, сколько до следующего часа. причем поскольку существуют полусдвинутые часовые пояса - то лучше точной отсчета брать именно время сервера а не клиента. ну а на клиенте уже жаваскриптом это значение оживлять и уменьшать ежесекундно.
     
  16. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @antonio21 а что мешает тебе нормально цитировать сообщения?
    Тема изначально в этом разделе находится, или кто-то из модераторов подвинул?
     
  17. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Начнем с генерации страницы:

    Получается мы создаем файл с пользовательскими функциями?
    Что-то типо functionsKonkursa.php и потом его вызываем когда пользователь кликает:

    // Подключаем файл с параметрами подключения к СУБД
    require_once('database.php');

    // отправляем данные в бд:
    $fields['id_user'] = ($_POST['id_users']); //если все ок

    // Если этот id уже добавлен,то будет сообщение об ошибке.

    $errors['id_user'] = checkID($fields['id_user']) === true ? : checkID($fields['id_user']);

    // Если баланс меньше 1 не пройдет проверку, будет сообщение об ошибке
    $errors['balance'] = checkBalance($balance) = "0" ? : checkBalance($balance);

    Так? Не понимаю это верно или нет, но знаю что не работает))
    --- Добавлено ---
    Нет, просто не обратил внимание, впервые на форуме!)
     
  18. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    святая корова! тебя кто программированию учит? что это за говнокод с дублирующими вызовами?
     
  19. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Ни кто не учит, а значит все подряд, ты учишь и все остальные учат.
     
  20. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ну ты на всех-то не вали. У тебя своя голова на плечах должна быть. Вот ты пишешь:
    Код (Text):
    1. checkID($fields['id_user']) === true ? : checkID($fields['id_user']);
    что значит выполнить функцию чекайди с таким-то аргументом, и если результат выполнения тождественно не равен логической истине, то выполнить эту же функцию еще раз с этим же аргументом.

    А потом ты пишешь еще одну конструкцию в подобном стиле, но в ней примечателен другой момент:
    Код (Text):
    1. checkBalance($balance) = "0" ? : checkBalance($balance);
    слева от вопроса стоит дословно "присвоить значение "строка ноль" результату выполнения функции чекБэлэнс" не важно с каким аргументом.
     
  21. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Тогда с простого, проверяем есть ли юзер и если его нет, то записываем его в базу конкурса и списываем 1.
    а если так? :
    PHP:
    1. <?php
    2. $fields['id_user'] = ($_POST['id_users']);
    3.  
    4. $result = mysql_query("SELECT * FROM `konkurs` WHERE id_user = '$id_user'") or die ("Error.<hr>" . mysql_error());
    5.  
    6. if (mysql_num_rows($result)) {
    7.     print "success=1";
    8. } else {
    9.     print "success=0";
    10. }
    11.  
    12. if ($result = true) {
    13. $update = "UPDATE `konkurs` SET `id_users` = ($_POST['id_user']);)
    14. $update = "UPDATE `users` SET `balance` = -1;)
    15. }
    16. ?>
     
  22. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Прокомментируй каждую лексему каждой строки.
    Ты не замечаешь, что даже форумный хайлайтер видит ошибки в синтаксисе? Ну это ладно. Пока давай расскажи что и зачем.
     
  23. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    1. Как-то так:

      PHP:
      1. <?php
      2. $fields['id_users'] = ($_POST['id_user']);     //получаем id_user id юзера
      3. $result = mysql_query("SELECT * FROM` anime `WHERE` id_users `=.$ id_user. '") or die ("Error.<hr>" . mysql_error()); //проверяем существует ли он уже
      4. if (mysql_num_rows($result)) {   // проверяем есть ли он, есть ли есть, то 0 если нет то 1
      5.     print "success=1";
      6. } else {
      7.     print "success=0";
      8. }
      9. if ($result = true) {  //если все ок, то пишем в бд:
      10. $update = "UPDATE `konkurs` SET `id_users` = +$id_user;) // пишем в таблицу конкурса в id_users айди юзера
      11. $update = "UPDATE `users` SET `balance` = -1;) списываем 1 балл.
      12. }
      13. ?>
     
  24. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Я не просил прокомментировать код. Я, пользуясь своим опытом и головой, и так его неплохо прочитал и додумал. Я просил описать каждую лексему того бреда, который тут написан.
    Например:
    $fields['id_users']=($_POST['id_user']); //получаем id_user id юзера
    Присвоить ключу айдиюзерс массива в переменной филдс значение айдиюзер из суперглобального массива _пост, который за каким-то неведомым фигом обернут в круглые скобки.

    Или:
    $result = mysql_query("SELECT * FROM` anime `WHERE` id_users `=.$ id_user. '") or die ("Error.<hr>" . mysql_error());//проверяем существует ли он уже
    Выполнить запрос в котором грависы разметало к чертям, но мы вдруг работаем со значением переменной айдиюзер, которую внимательный читатель встречает впервые. А возможно и программа тоже в ахуе. Выбираем мы из таблицы анимэ, название которой очень подходит под то, чтоб в ней хранить пользователей. Ну а если запрос обломался - умираем с сообщением об ошибке.

    if($result=true){//если все ок, то пишем в бд:
    ВСЕГДА ПИШЕМ В БАЗУ потому что "присвоить переменной резалт значение булевой истины" не может иметь никакого логического значения, кроме этой же булевой истины.

    $update="UPDATE `konkurs` SET `id_users` = +$id_user;) // пишем в таблицу конкурса в id_users айди юзера
    На самом деле это читается как присвоить такой-то текст такой-то переменной. До выполнения запроса тут еще далеко. Сам текст: присвоить полю айди_юзерс значение переменной айди_юзер, сделав это для всех кортежей в таблице конкурсов. То есть каждый следующий участник будет постоянно затирать ВОООБЩЕ НАХЕР ВСЕХ участников всех предыдущих конкурсов. И пхп-синтаксис нарушен.

    $update = "UPDATE `users` SET `balance` =-1;) списываем 1 балл.
    Не. На самом деле "пиздим у всех пользователей все их баллы, оставляя по бесполезному отрицательному балансу". Охренеть. Ты не Мавроди случаем? И почему юзерс а не анимэ? И да, пхп-синтаксис нарушен.
     
    igordata и Molder1613 нравится это.
  25. antonio21

    antonio21 Новичок

    С нами с:
    22 авг 2016
    Сообщения:
    61
    Симпатии:
    0
    Да, так не айс, эх, блин. Не понимаю я много. Может есть примеры или на этом примере можешь помочь разобрать?