Как дойти до 120, отсчитывая PHP скриптом по +1 каждый час?
Суть:
В БД есть записи с пользователями, ники и id которых повторяются повторяются. Каждый час скрипт должен начислять по 10 очков. Всего выполнений должно быть 120. Т.е., если у пользователя было 0 очков, за 120 часов ему должно накапать 1200 очков, после 120 выполнений, скрипт должен игнорировать этого пользователя, но считать остальных пользователей.
Что я пробовал? cron:
Проверяем пользователя на 120 выполнений, если 120 есть - игнорируем, если нет, то берем предыдущее время выполнения скрипта (из БД), если оно меньше или равно настоящему времени, то добавляем очки, делаем предыдущее кол-во выполнений + 1, так же делаем предыдущее время выполнения + 3600 сек. Но тут скрипт обновит эти данные для всех пользователей. Как тут быть?
Добавить на страницу, что бы код срабатывал при заходе на неё пользователя:
Тут так-же как и в cron, только пользователь может не заходить на страницу более 120 часов и кол-во очков могут перевалить за 1200. Пытался сделать так:
Настоящее время - время предыдущего выполнения / 3600. Округляем это и получаем количество "кругов".
Проверяем: кол-во уже сделанных "кругов" + те, что только что получили. Если больше 120, то тут я пробовал запихнуть в цикл, где от полученного вычитается 1 и так, пока не будет 120, потом из полученных считаем очки. Но и тут, данные обновятся для всех строк с ником или id пользователя, да и считать такое циклом - большая нагрузка.
ну так сделай какое-нибудь уникальное поле, что будет отличать пользователей. Допустим отдельный ид в таблице. И начисляй по этому иду а не по пользователям. По сути то тебе какая разница кто там, плюсануть то строчку надо в базе. выборку делать чета типа
UPDATE `table` SET `score`=`score`+5, `count`=`count`+1, `timestamp`= ADDTIME(`timestamp` , '01:00:00') WHERE `id` in (SELECT `id` FROM `table` WHERE `count`<=120 AND `timestamp` >= NOW() - INTERVAL 1 HOUR);
Создаем бд запись где храним - ид пользователя и очки. Раз в час(крон) грузим всех пользователей которые онлайн(online > 0), перебираем всех пользователей, грузим данные о их очках. Если очки == 120 - не выполнять, если нет - повышаем (передаем в Sql запросе WHERE `id` = id)
По поводу онлайна, на определенное действие на сайте(которое всегда вызывается когда пользователь на сайте) поставьте запись в поле БД(к примеру поле online) = 5. Ставим крон на каждую минуту, перебираем всех пользователей WHERE online > 0 и уменьшаем им online(online--), тем самым онлайн будет обновляться каждые 5 минут. Если чел на сайте - он 5 минут будет светится онлайн, если за 5 минут он опять не появится на сайте(не запишет его скрипт в бд как online = 5) то ему присвоеться значение 0(online) - пользователь оффлайн.
Valeri Lavrov: ведь когда проверяем данные можно дополнительно запросить id или nickname (первичный ключ) и уже по нему обновить в дополнительном запросе. Или всё зафигачить в один запрос с проверками (а еще лучше было бы поставить процедурку (php.net/manual/ru/mysqli.quickstart.stored-procedu..., которую можно вызывать кроном на сервере и вообще не трогать php)