За последние 24 часа нас посетил 20521 программист и 979 роботов. Сейчас ищут 745 программистов ...

Задержка смены анекдотов. Как реализовать?

Тема в разделе "PHP для новичков", создана пользователем Евгений Владимирович, 29 май 2024.

  1. Евгений Владимирович

    Евгений Владимирович Активный пользователь

    С нами с:
    3 май 2009
    Сообщения:
    24
    Симпатии:
    0
    Есть простой скрипт
    Выводящий анекдот из файла
    Подключается через include_once
    При каждом обновлении страницы- новый анекдот соответственно
    Подскажите
    Как ограничить смену анекдотов, чтобы за одну секунду не могло выводиться 25 анекдотов например одному пользователю при перезагрузка х страницы. Как это реализовать. Чтобы стояла задержка смены - не чаще одного анекдота в три секунды например ??
    Сам скрипт:
    <?php
    $file = file('anekdot.dat');
    $max_rnd = count($file);
    $rnd_frase = mt_rand(1,$max_rnd);
    $content = "<div>".$file[$rnd_frase]."</div>";
    $content1 = mb_convert_encoding($content, 'windows-1251', 'utf-8');
    echo $content1;
    ?>
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.835
    Симпатии:
    741
    Адрес:
    Татарстан
    1. Чтоб однозначно определить - тот же это пользователь или нет, нужно применять регистрацию, авторизацию. Если для неавторизованнвх хотите - та еще заморочка.... нужно цифровой слепок барузера делать через js, еще можно к ip привязываться
    2. Нужно где-то хранить счетчик показа анекдотов для конкретного пользователя - или записывать в файл или лучше в БД. Записываете время просмотра для каждого просмотра. При записи, предварительно удаляете те элементы - которые уже не укладываются в ваш временной интервал
    3. Перед выводом анекдота - смотрите кол-во записей о просмотре данным пользователем - смотрите - все ли они укладываются в аш промежуток - и только если так - показываете

    вот так ... такая вроде-бы простая формулировка задачи - влечет нехилые затраты.

    Подумайте - а оно вообще вам надо? Ну посмотрит 40 анекдотов - жалко чтоли? )))
     
  3. Survivor

    Survivor Новичок

    С нами с:
    8 фев 2023
    Сообщения:
    76
    Симпатии:
    13
    Если прям не упарываться, вряд ли ты банкир, желающий рассмешить своих клиентов.
    Этого может быть вполне достаточно.

    anekdot.php
    PHP:
    1. <!DOCTYPE html>
    2. <html lang="ru">
    3. <head>
    4.     <meta charset="UTF-8">
    5.     <title>Анекдоты</title>
    6.     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    7.     <style>
    8.         #anekdot-container {
    9.            font-size: 20px;
    10.             margin: 20px;
    11.         }
    12.     </style>
    13. </head>
    14. <body>
    15.     <div id="anekdot-container">Загрузка анекдота...</div>
    16.  
    17.     <script>
    18.         function show_anekdot()
    19.         {
    20.             $.ajax({
    21.                 url: 'ajax_anekdot.php',
    22.                 type: 'POST',
    23.                 dataType: 'json',
    24.                 success: function( data )
    25.                 {
    26.                     if (data.error)
    27.                     {
    28.                         return $('#anekdot-container').text(data.error);
    29.                     }
    30.  
    31.                     if ( data.anekdot )
    32.                     {
    33.                         $('#anekdot-container').html("<div>" + data.anekdot + "</div>");
    34.                         //- можно использовать append
    35.                     }
    36.                 },
    37.                 error: function()
    38.                 {
    39.                     $('#anekdot-container').text('Ошибка при загрузке анекдота.');
    40.                 }
    41.             });
    42.         }
    43.  
    44.         // Отображение первого анекдота сразу после загрузки страницы
    45.         show_anekdot();
    46.  
    47.         // Показываем новый анекдот каждые 10 секунд
    48.         setInterval(show_anekdot, 10000);
    49.     </script>
    50. </body>
    51. </html>

    ajax_anekdot
    PHP:
    1. <?php
    2. declare(strict_types = 1);
    3. header('Content-Type: application/json');
    4.  
    5. if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    6. {
    7.   $anekdot = file('anekdot.dat', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    8.  
    9.   // Проверка на наличие анекдотов
    10.   if ( $anekdot === false || empty( $anekdot ) )
    11.   {
    12.     exit( json_encode(['error' => 'Не с чего ржать']) );
    13.   }
    14.  
    15.   // Возвращаем анекдот в формате JSON
    16.   exit ( json_encode(['anekdot' => $anekdot[array_rand($anekdot)]]) );
    17. }
    Файл с анекдотами
    Код (Text):
    1.  
    2. Анекдот 1
    3. Анекдот 2
    4. Анекдот 3

    Ну, а если прям хочешь защититься:
    - Проверяй заголовки $_SERVER['HTTP_ORIGIN']
    - Создай какой-нибудь ключик api и проверяй его в ajax файле
    - Если регистрации нет, можно json файлик с сохранением IP юзера (+ чего угодно ещё) и ограничением кол-ва запросов
    либо pid файлик и ограничивать вообще всех))
     
  4. Serg197211

    Serg197211 Новичок

    С нами с:
    23 фев 2024
    Сообщения:
    4
    Симпатии:
    1
    Зачем такие сложности? Всё можно в сессии хранить. В начале скрипта session_start(), и хранить в сессии ассоциативный массив, например "номер анекдота" => timestamp показа. И при показе соответственно учитывать информацию из этого массива
     
  5. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    291
    Симпатии:
    57
    Адрес:
    Бавария, Германия
    Добрый день!
    Вы отправляете по ajax-запросу только одну строку из файла $anekdot
    PHP:
    1.  exit ( json_encode(['anekdot' => [array_rand($anekdot)]]) );
    Не понятно зачем для этого нужен JSON Response. Я бы просто отправлял и получал html текст.
    Удачи!
    --- Добавлено ---
    Согласен с Вами. Сложная идентификация клиента в данном случае не нужна.
    Однако сохранение в сессии не подходит из-за того, что она создаётся на сеанс и имеет ограниченное время жизни.
    Поэтому правильнее использовать Куки.
    --- Добавлено ---
    Уточните, пожалуйста, это:
    "чтобы за одну секунду не могло выводиться 25 анекдотов например одному пользователю при перезагрузка х страницы."
    Каждый анекдот в одну строку?
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.773
    Симпатии:
    1.322
    Адрес:
    Лень
    @Survivor $anekdot === false достаточно empty
    --- Добавлено ---
    Юзер зашел с приватной вкладки. Куки пока.
    --- Добавлено ---
    Или лично с инструмента del куку сделал. Ну а если парсить сайт начнут. Тут не сессия, не куки, а нужно запрет на не авторизованных юзеров
     
  7. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    291
    Симпатии:
    57
    Адрес:
    Бавария, Германия
    Вообще-то о авторизации юзеров Евгений Владимирович ничего не писал. Вероятно её и нет вовсе.
    А если не сессия, не куки, то должна быть проверка и должно быть определено, что делать.
    Типа, не показывать анекдоты анонимному юзеру, или, если показывать, то как.
     
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.773
    Симпатии:
    1.322
    Адрес:
    Лень
    я про что писал в своем последнем посту ?
     
  9. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.478
    Симпатии:
    281
    Похоже, что, изначально, автора это и беспокоит. Раз таймаут видит решением.
    Как выше уже предлагали, сессий для этого вполне достаточно.
    Только выдавать нужно не случайный анекдот, а следующий по списку
     
  10. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    291
    Симпатии:
    57
    Адрес:
    Бавария, Германия
    MouseZver,
    Это должно быть определено в постановке задачи.
    Более очевидное в этом случае решение показывать случайный анекдот.
    Между прочим. Что значит запрет? Убирать весь блок анекдотов?
    Придётся мудрить с разметкой.

    Согласен.
    Только сколько потребуется уникальных анекдот для того чтобы делать обновления каждые три секунды?

    P.S. Делал один партийный сайт и там был блок политических анекдотов. Примерно такая же идея была у владельца ресурса.
    Анекдоты закончились на следующий день после запуска сайта.
     
  11. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.773
    Симпатии:
    1.322
    Адрес:
    Лень
    Это выход который я предлагаю, а Автора беспокоит совсем другое.

    Как выше описывал, сессией не достаточно если на нее онли делать показ текст. Еще раз повторю.

    Вообще-то случайный, см. код автора o_O Только добавить немного надо - что тип посмотрел этот текст и нужно другой показать.


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


    ;)

    Пишите ему авторизацию, а не просто на куках/сессиях пилить тайм аут, который благополучно обойду приватной вкладкой.
     
  12. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.077
    Симпатии:
    1.237
    Адрес:
    там-сям
    Ребята, проще надо быть.

    Раз НЕ ставится условие что последовательность выдачи анекдотов должна быть уникальной для каждого пользователя, будем менять выдачу для всех одинаково!

    Пишем функцию которая меняет результат не чаще, чем раз в три секунды (или сколько мы решим).

    PHP:
    1. function lazyTimer(int $interval = 3): int {
    2.   return intval(time() / $interval);
    3. }
    Очевидно результат будет большим целым числом. А нам надо впихнуть его в промежуток 0 .. totalPageNum-1 .
    Это будет "номер страницы":
    PHP:
    1. $page = lazyTimer(3) % $totalPageNum;
    @Евгений Владимирович Используй этот номер чтобы читать определенные строки из своего файла. Детали уже сам додумай...
    с тебя пиво
    --- Добавлено ---
    P.S. Если кому-то кажется, что он прочитал требование что надо идентифицировать пользователя или что надо проверять не читал ли он уже этот случайный анекдот в прошлый раз — перечитайте о чем попросил ТС. Не было такого!
     
  13. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.773
    Симпатии:
    1.322
    Адрес:
    Лень
    Вот тут как раз двух смысловой контекст. Новый анекдот показать и не важно был он показан в предыдущий раз. Новый анекдот считается как новый, не показывая одно и тоже с пред.
    --- Добавлено ---
    Про идентификацию - при хорошем раскладе, она нужна чтобы сейвить тайм, иначе вот это всё что тут разжёвывается - не о чем.
    --- Добавлено ---
    Или можно совсем по иному пути пойти. Делать lock на стороне сервера со значением id или текст анекдота, а потом чекать его просроченность по дате. Любой запрос обновляет значение если тайм разрешает и сейвим для всех пользователей.
     
  14. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    291
    Симпатии:
    57
    Адрес:
    Бавария, Германия
    При любом раскладе потребуется очень много анекдотов.
    Может просто по номерам? например,