В примере ниже будет рассмотрен вариант именно для WordPress, хотя подобный метод подойдёт для любого сайта.
Часто на хостингах можно столкнуться с непомерной нагрузкой которую создаёт сайт, хотя Яндекс Метрика упорно показывает 100 чел в сутки, AwStats датё объёмную информацию, но о количестве заходов с каждого IP информацию не предоставляет(хотя косвенно можно понять частоту по объему трафика).
Итак, задача, понять как часто и какие IP ходят на ваш сайт под управлением WordPress, что бы в дальнейшем заблокировать IP адреса создающие большую нагрузку на сайт. Блокировка предполагается по суммарному количеству запросов в интервале времени.
Для этого понадобится таблица куда будем сохранять данные, её код CREATE ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
CREATE TABLE `wp_visiters_bot` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `ip` VARCHAR(300) NULL DEFAULT NULL, `browser` VARCHAR(500) NULL DEFAULT NULL, `cnt` INT(11) NULL DEFAULT NULL, `request` TEXT NULL, `input` TEXT NULL, `data_update` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE INDEX `ip` (`ip`) ) COMMENT='' COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1 ; |
Делаем поле ip уникальным, что бы обновлять и вставлять запись за один MySQL запрос. Ниже код вставки нужных значений в БД:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
global $wpdb; include_once dirname(__FILE__) . '/wp-admin/includes/class-wp-community-events.php';//для работы класса WP_Community_Events $ip = WP_Community_Events::get_unsafe_client_ip(); $browser = esc_sql($_SERVER['HTTP_USER_AGENT']);//информация о браузере клиента $request = esc_sql(wp_json_encode($_REQUEST));//Json всего запроса $input = esc_sql(file_get_contents('php://input'));//Сырые данные из body $cnt = 1;//начальное количество //Запрос к бд на вставку с обновлением $query = <<<EOT INSERT INTO wp_visiters_bot (`ip`,`browser`,`cnt`,`request`,`input`) VALUES ('{$ip}','{$browser}','{$cnt}','{$request}','$input') ON DUPLICATE KEY UPDATE cnt=cnt+1,request=VALUES(request),input=VALUES(input),browser=VALUES(browser) EOT; $wpdb->query($query); |
В целом код выше, прокомментирован, пояснить стоит лишь:
1 2 3 |
ON DUPLICATE KEY UPDATE cnt=cnt+1,request=VALUES(request),input=VALUES(input),browser=VALUES(browser) |
Суть такова, когда при вставке записи обнаруживается ошибка о дубликате нашего уникального ключа (ip адрес), то MySQL без лишних вопросов обновляет данные
- cnt возьмётся из бд и увеличивается на +1
- Остальные данные берутся из запроса INSERT VALUES, о чём свидетельствует конструкция вида «имя_поля=VALUES(имя_поля)»
- Минусом в таком запросе (для эстетов) будет то что id авто инкремента будет не по порядку(пример на скриншоте ниже)
И так, пока писался этот материал у нас получилась такая статистика по запросам и IP
Статья писалась в течении 5-и минут и за это время набежала некоторая статистика, получается что некоторые адреса ходят на сайт слишком часто. Возможно это парсеры или сума сошедшие сервисы. В любом случае для полной картины оперировать только этими данными нельзя, но определённая картинка о «ходящих на сайт» складывается.
Код можно повесить на какой нибудь хук (например хук init), но в нашем случае необходимо было сделать это до загрузки функционала WordPress и код был добавлен в файл wp-load.php
Помните, добавлять что либо в файлы ядра не самая лучшая затея и вы должны понимать.
«Ниже код вставки нужных значений в БД:»
Не в БД, думаю, а в какой-то файл. В какой? function.php, index.php?
дочитал, вопрос снят, спасибо)
Эту же статью мы публиковали на Хабре, там есть большое количество комментариев.