Способ предотвращения создания посетителем более 2 сообщений в день (PHP MySQL)

#php #mysql #sql #timer #limit

#php #mysql #sql #таймер #ограничение

Вопрос:

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

Вот ситуация: В настоящее время я создаю веб-сайт, и у меня есть раздел, где посетители могут размещать сообщения, что-то вроде «гостевой книги». Однако я хочу ограничить IP-адрес до 2 сообщений в день. Сначала я подумал, что это будет легко, просто вставьте IP-адрес, дату и время вместе со всеми другими данными в таблицу mysql, а затем выполните сравнение времени и дат с каждого ip. Что-то вроде этого…. Затем, когда я приступил к работе над этим, в голову пришло так много вопросов. Как я буду сравнивать записи, если IP-адрес опубликовал более 2 сообщений за несколько дней? Как бы вы вообще начали точно сравнивать дату и время? Какой формат даты и времени является наилучшим для сравнения? Есть ли лучший способ, такой как данные с истекающим сроком действия, с которыми вы можете сравнить? И так далее.. Извините, если это кажется такой простой задачей, но мне трудно найти ответы. Пробовал гуглить все, например «ограничение по времени mysql php», «таймер предотвращения спама php mysql», «таймер php mysql для просмотра megavideo» и т.д.

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

Заранее благодарю вас!

Комментарии:

1. Является ли два сообщения в день «двумя сообщениями с интервалом в 24 часа» или «двумя сообщениями в одну и ту же дату» — это означает, что вы можете опубликовать два сообщения в 23: 59 по серверному времени, а затем еще два в 00: 01? Ваши ответы ниже отражают сообщения с интервалом в 24 часа, в основном.

Ответ №1:

Создайте таблицу с именем exceptions со структурой id, ip, date

и когда пользователь публикует что-либо, выполните запрос типа :

 $ip = $_SERVER['REMOTE_ADDR'];
$query = "insert into exceptions set ip = '{$ip}',date = 'NOW()'";
  

и прежде чем разрешить пользователю публиковать что-либо, добавьте это:

 $ip = $_SERVER['REMOTE_ADDR'];
$count = mysql_num_rows(mysql_query("select count(*) 
         from exceptions where ip = '{$ip}' 
         and date > DATE_SUB(NOW(), INTERVAL 24 HOUR)"));

if($count> 2) { 
  echo 'You have exceeded posting limits, please try again in 24 hours';
  exit; 
}
  

Комментарии:

1. количество в mysql_query должно быть устранено. запрос возвращает число, и mysql_num_rows всегда будет единицей.

Ответ №2:

что-то вроде этого:

 posts_in_last_24_hours = select count(*) from posts where ip=? and date>(NOW()-86400) -- 24 hours ago
if that is 2:
    fail
else:
    post message
  

Комментарии:

1. Спасибо за это, я постараюсь посмотреть, смогу ли я заставить это работать!

Ответ №3:

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

  SELECT COUNT (IP) FROM posts_log WHERE IP = 'the_user_ip' AND post_date > (NOW() - (X * (60 * 60 * 24)))
  

Ответ №4:

Использование триггера

Запишите IP и сохраните его в таблице гостевой книги.

Затем создайте триггер, подобный этому:

 DELIMITER $$

CREATE TRIGGER bi_guestbook_each BEFORE INSERT ON guestbook FOR EACH ROW
BEGIN
  DECLARE posts_today INTEGER;

  SELECT COUNT(new.ip) INTO posts_today FROM guestbook 
    WHERE ip = new.ip AND postdate = new.postdate;
  IF posts_today > 1 THEN BEGIN
    //Force error by selecting from non-existing table
    //this will prevent the insert from happening.
    SELECT no_more_than_2_post_per_day_allowed 
     FROM before_insert_guestbook_error;
  END; END IF;

END$$

DELIMITER ;
  

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

Используя insert .. select

Если вы не хотите использовать триггеры, используйте insert … инструкция select.

Сначала убедитесь, что это поле ip определено в определении таблицы как NOT NULL без значения по умолчанию.
Это приведет к сбою следующей вставки при попытке вставить нулевое значение в таблицу гостевой книги.

 <?php
  $name = mysql_real_escape_string($_GET['name']);
  $post = .....
  $ip = ....
$query = "INSERT INTO guestbook (id, name, post_text, ip, postdate) SELECT
            NULL AS id
            , '$name' AS name
            , '$post' AS post_text
            , IF(guestbook.count(*)>=2,null,ip) AS ip
            , CURDATE() AS postdate
          FROM guestbook WHERE ip = '$ip' AND postdate = CURDATE()";
  

Конечно, вы можете поместить IF(count(*) >= 2,null,...) вместо любого столбца, который определен как NOT NULL в определении таблицы.

Ссылки:
выберите … вставить:http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
триггеры:http://dev.mysql.com/doc/refman/5.1/en/triggers.html

Комментарии:

1. С точки зрения стиля, я не думаю, что триггер был бы правильным способом сделать это — если вы не мастер базы данных, триггеры могут быть очень сложными для понимания и отладки, и я видел, как команды боролись с необъяснимым поведением в течение нескольких дней, потому что никто не помнил, что триггер был настроен на таблицу и срабатывал неожиданным образом…

2. Привет, спасибо за ваш ответ. Я все еще довольно новичок в mysql и php и я еще не узнал о триггерах. Я изучу ваш код и попробую его. Большое вам спасибо!

Ответ №5:

Вы могли бы реализовать это просто с помощью файлов cookie. Любой, кто достаточно решителен, чтобы обойти ограничение на публикацию, сможет обойти блокировку IP в любом случае, поскольку прокси и динамические IP-адреса делают это действительно простым.Таким образом, блокировка с помощью cookie или по IP примерно так же полезны, как и друг друга (не особенно), но файлы cookie проще реализовать:

Если вы сохраните счетчик в cookie и установите дату истечения срока действия на 24 часа в будущем. Затем вы можете увеличить счетчик, когда пользователь публикует запись, и просто проверить счетчик, чтобы увидеть, достигли ли они своего предела.

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


Основываясь на точке captcha Невилла К. Если вас больше всего беспокоит спам, попробуйте использовать отрицательную капчу — это не повлияет на работу пользователя, поскольку они ее никогда не видят.

Комментарии:

1. -1 можно легко отключить или удалить cookies и продолжать рассылать спам на сайт

2. да, и они могут так же легко изменить ip. отсюда и преамбула об этом.

Ответ №6:

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

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

Комментарии:

1. Привет, спасибо за ответ! Я внедрил простую систему captcha, в которой я храню массив вопросов и ответов в файле php, а затем сравниваю их после отправки формы с помощью ajax. Моя цель — просто ограничить некоторых болтливых посетителей от рассылки спама. Спасибо за вашу заботу!