Розы в саду можно размножать не только методом черенкования, но и через прививку на куст шиповника. Данное мероприятие обладает множеством особенностей и нюансов, которые мы разберём в данной статье.
Как прививаются розы на шиповник, особенности прививки
Для начала перечислим список необходимых условий для того, чтобы прививка прошла успешно:
- Куст шиповника должен быть возрастом от трёх до шести лет;
- Диаметр стеблей куста шиповника – от одного см;
- Прививать розу нужно в начале весны или в конце лета (в конце августа);
- Толщина стебля розы нужна от 7 мм;
- Для прививки используются спящие почки отцветших побегов розы.
- Как происходит процесс прививки розы на шиповник?
Весь процесс можно условно разделить на несколько основных шагов:
- До начала прививки нужно обильно полить как куст шиповника (для
стимуляции сокодвижения), так и побег розы. - На следующий день отгребается почва от куста шиповника до того, пока не проявится первый корешок. Корешок тщательно очищается от земли (в идеале его нужно промыть влажной тканью, чтобы избежать попадания грунта в будущий разрез, так как в этом случае побег загниёт).
- На шейке корневища создаётся Т-образный разрез (2 сантиметра вертикально и 1 – горизонтально). Аккуратно отворачивается кора в разные стороны.
- В надрез заводится щипок, приматывается пластиковой лентой, а шейка корневища аккуратно присыпается влажной землёй.
- Спустя две недели можно констатировать результат: почка приживётся, если станет зелёной и не приживётся, если почернеет.
- Через месяц можно снимать пластиковую ленту.
Как ухаживать за привитой розой?
После того, как вы привили почку, нужно соблюдать следующие правила ухода:
- Каждую неделю производите прокалывание земли возле куста и хороший полив;
- Ближе к наступлению холодов нужно окучить куст и присыпать сверху сухими (опавшими) листьями.
- К середине весны нужно вновь оголить куст до шейки и обрезать на 0.5 см выше того места, куда была привита роза.
- После того, как привитые ростки начинают расти, и на них появляется 3-5 свежих листочков, побег нужно прищипнуть для того, чтобы стимулировать ветвление будущей розы.
- В период формирования бутонов (в первый год) их нужно убирать для того, чтобы побеги успели набраться сил и вызреть – в этом случае на следующий год куст будет сильным и обильно цветущим.
- Ближе к осени куст будет пригоден для того, чтобы выкапывать его и пересаживать но новое место.
Какие ошибки допускаются? Как можно «упустить» розы в шиповник?
Существует несколько распространённых ошибок и недочётов, которые можно допустить при прививании розы на шиповник. Среди самых распространённых следующие:
- Недостаточно качественная прививка, в результате которой отмирает надземная часть растения – в этом случае появится не побег розы, а обычный побег шиповника.
- Попадание грязи в разрез на корне – в этом случае скорее всего произойдёт загнивание.
- Недостаточно толстый росток розы – в этом случае велика вероятность, что он не приживётся и попросту погибнет.
- Оставление бутонов в первый год цветения привитого куста – если не убирать их, куст будет недостаточно сильным и не даст обильного цветения.
https://nmu2.ru/new/index.php?sub1=sustaflexUZhous011&sub2={feed}&sub3={site}&sub4={os}&sub5={user_activity}&utm_source=Push.house&utm_medium={city}&utm_campaign={browser}&utm_content={format}
ПРАВИЛЬНАЯ АРХИТЕКТУРА (как делают опытные)
Файлы будут такие:
/public_html/
├── index.php ← преленд
├── logger.php ← логгер после 2-го шага
├── ips_raw.txt ← ПОДРОБНЫЙ лог (IP + UA + сабы)
├── ips_good.txt ← ТОЛЬКО IP, по одному в строке
└── ip_stats.php ← (опционально) аналитика
УЛУЧШЕННЫЙ logger.php
<?php
// —————- НАСТРОЙКИ —————-
$rawLogFile = “ips_raw.txt”;
$goodIpFile = “ips_good.txt”;
$maxPerIp = 3; // максимум логирований одного IP
$denyUAwords = [‘Headless’, ‘bot’, ‘crawl’, ‘spider’, ‘curl’];
// —————- ДАННЫЕ —————-
$ip = $_SERVER[‘REMOTE_ADDR’];
$ua = $_SERVER[‘HTTP_USER_AGENT’] ?? ”;
$sub1 = $_GET[‘sub1’] ?? ”;
$sub2 = $_GET[‘sub2’] ?? ”;
$sub3 = $_GET[‘sub3’] ?? ”;
$sub4 = $_GET[‘sub4’] ?? ”;
$sub5 = $_GET[‘sub5’] ?? ”;
// —————- ФИЛЬТР IP —————-
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
exit;
}
// —————- ФИЛЬТР UA —————-
foreach ($denyUAwords as $bad) {
if (stripos($ua, $bad) !== false) {
exit;
}
}
// —————- СКОЛЬКО РАЗ УЖЕ БЫЛ IP —————-
$rawData = file_exists($rawLogFile) ? file($rawLogFile, FILE_IGNORE_NEW_LINES) : [];
$ipCount = 0;
foreach ($rawData as $line) {
if (strpos($line, “IP:$ip”) !== false) {
$ipCount++;
}
}
if ($ipCount >= $maxPerIp) {
exit;
}
// —————- ПОДРОБНЫЙ ЛОГ —————-
$rawLine = date(“Y-m-d H:i:s”)
. ” | IP:$ip”
. ” | UA:$ua”
. ” | sub1:$sub1″
. ” | sub2:$sub2″
. ” | sub3:$sub3″
. ” | sub4:$sub4″
. ” | sub5:$sub5″;
file_put_contents($rawLogFile, $rawLine . PHP_EOL, FILE_APPEND);
// —————- GOOD IP —————-
$goodIps = file_exists($goodIpFile) ? file($goodIpFile, FILE_IGNORE_NEW_LINES) : [];
if (!in_array($ip, $goodIps)) {
file_put_contents($goodIpFile, $ip . PHP_EOL, FILE_APPEND);
}
<?php
// —————- НАСТРОЙКИ —————-
$rawLogFile = “ips_raw.txt”;
$goodIpFile = “ips_good.txt”;
$badIpFile = “bad_ips.txt”;
$maxPerIp = 3;
$minDelta = 900; // МИНИМАЛЬНЫЙ ТАЙМИНГ (мс)
$denyUAwords = [‘Headless’, ‘bot’, ‘crawl’, ‘spider’, ‘curl’];
// —————- ДАННЫЕ —————-
$ip = $_SERVER[‘REMOTE_ADDR’];
$ua = $_SERVER[‘HTTP_USER_AGENT’] ?? ”;
$delta = intval($_GET[‘delta’] ?? 0);
$sub1 = $_GET[‘sub1’] ?? ”;
$sub2 = $_GET[‘sub2’] ?? ”;
$sub3 = $_GET[‘sub3’] ?? ”;
$sub4 = $_GET[‘sub4’] ?? ”;
$sub5 = $_GET[‘sub5’] ?? ”;
$time = date(“Y-m-d H:i:s”);
// —————- BAD LOGGER —————-
function logBad($reason, $ip, $ua, $delta, $sub1, $sub2, $sub3, $sub4, $sub5, $time, $file) {
$line = “$time | REASON:$reason | IP:$ip | UA:$ua | DELTA:$delta ms | sub1:$sub1 | sub2:$sub2 | sub3:$sub3 | sub4:$sub4 | sub5:$sub5”;
file_put_contents($file, $line . PHP_EOL, FILE_APPEND);
}
// —————- IP CHECK —————-
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
logBad(“INVALID_IP”, $ip, $ua, $delta, $sub1, $sub2, $sub3, $sub4, $sub5, $time, $badIpFile);
exit;
}
// —————- UA CHECK —————-
foreach ($denyUAwords as $bad) {
if (stripos($ua, $bad) !== false) {
logBad(“BAD_UA”, $ip, $ua, $delta, $sub1, $sub2, $sub3, $sub4, $sub5, $time, $badIpFile);
exit;
}
}
// —————- TIMING CHECK —————-
if ($delta > 0 && $delta < $minDelta) {
logBad(“BAD_TIMING”, $ip, $ua, $delta, $sub1, $sub2, $sub3, $sub4, $sub5, $time, $badIpFile);
exit;
}
// —————- REPEAT CHECK —————-
$rawData = file_exists($rawLogFile) ? file($rawLogFile, FILE_IGNORE_NEW_LINES) : [];
$ipCount = 0;
foreach ($rawData as $line) {
if (strpos($line, “IP:$ip”) !== false) {
$ipCount++;
}
}
if ($ipCount >= $maxPerIp) {
logBad(“IP_OVERLIMIT”, $ip, $ua, $delta, $sub1, $sub2, $sub3, $sub4, $sub5, $time, $badIpFile);
exit;
}
// —————- GOOD —————-
$rawLine = “$time | IP:$ip | UA:$ua | DELTA:$delta ms | sub1:$sub1 | sub2:$sub2 | sub3:$sub3 | sub4:$sub4 | sub5:$sub5”;
file_put_contents($rawLogFile, $rawLine . PHP_EOL, FILE_APPEND);
$goodIps = file_exists($goodIpFile) ? file($goodIpFile, FILE_IGNORE_NEW_LINES) : [];
if (!in_array($ip, $goodIps)) {
file_put_contents($goodIpFile, $ip . PHP_EOL, FILE_APPEND);
}
1 версия
готовый PHP-скрипт, который:
Читает
ips_good.txtГруппирует IP по
/24(то есть последние 8 бит варьируются, первые 3 октета фиксированы)Выдает диапазоны в виде
x.x.x.0/24Дополнительно можно фильтровать по feed (
sub2) на основеips_raw.txt, чтобы брать только проверенные источники
Вот скрипт:
<?php
/*
Скрипт: generate_whitelist.php
Берет ips_good.txt + ips_raw.txt
Группирует IP по /24 и выводит готовый whitelist
Опционально фильтрует по feed (sub2)
*/
// Файлы
$goodFile = ‘ips_good.txt’;
$rawFile = ‘ips_raw.txt’;
// Опциональный фильтр по feed (sub2)
$filterFeed = []; // например [‘feed123’, ‘feed456’], пустой = все feed
// Читаем хорошие IP
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
// Если фильтруем по feed, проверяем raw
if (!empty($filterFeed)) {
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$allowedIps = [];
foreach ($rawData as $line) {
// ищем sub2
if (preg_match(‘/sub2:([^\s|]+)/’, $line, $m)) {
$sub2 = $m[1];
if (in_array($sub2, $filterFeed)) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$allowedIps[] = $ipm[1];
}
}
}
}
// оставляем только те, которые есть в goodIps
$goodIps = array_intersect($goodIps, $allowedIps);
}
// Группируем по /24
$subnetMap = [];
foreach ($goodIps as $ip) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0/24”;
$subnetMap[$subnet] = true;
}
}
// Выводим готовый whitelist
echo “Готовый whitelist по /24:\n”;
foreach (array_keys($subnetMap) as $subnet) {
echo $subnet . “\n”;
}
echo “\nВсего диапазонов: ” . count($subnetMap) . “\n”;
🔹 Как пользоваться
Сохрани как
generate_whitelist.phpна сервере рядом сips_good.txtиips_raw.txtПри необходимости фильтровать feed, в
$filterFeedукажи массив с нужными feed, например:
Запусти в браузере или CLI:
Получишь список готовых диапазонов
/24, который можно копировать в push.house.
2 продвинутая версия
могу сделать ещё более продвинутую версию, которая:
показывает сколько IP в каждом /24
сортирует по количеству лидов
позволяет сразу решать, какие диапазоны добавлять, а какие нет
Это будет прямо полноценный анализатор whitelist.
полностью продвинутый скрипт-анализатор whitelist, который сразу даст тебе:
Группировку IP по
/24Подсчет, сколько IP попало в каждый диапазон
Фильтр по feed (
sub2)Возможность сортировать диапазоны по активности
Вывод готовый к копированию в push.house
Вот готовый код:
<?php
/*
Скрипт: analyze_whitelist.php
– Читает ips_good.txt и ips_raw.txt
– Группирует IP по /24
– Считает, сколько IP в каждом диапазоне
– Фильтрует по feed (sub2) если нужно
– Сортирует по активности
– Выводит готовый whitelist
*/
// Файлы
$goodFile = ‘ips_good.txt’;
$rawFile = ‘ips_raw.txt’;
// Опциональный фильтр по feed
$filterFeed = []; // пример: [‘feed123′,’feed456’]; пустой = все feed
// Читаем хорошие IP
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
// Если фильтруем по feed, проверяем raw
if (!empty($filterFeed)) {
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$allowedIps = [];
foreach ($rawData as $line) {
if (preg_match(‘/sub2:([^\s|]+)/’, $line, $m)) {
$sub2 = $m[1];
if (in_array($sub2, $filterFeed)) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$allowedIps[] = $ipm[1];
}
}
}
}
// оставляем только те, которые есть в goodIps
$goodIps = array_intersect($goodIps, $allowedIps);
}
// Группируем по /24 и считаем IP
$subnetMap = [];
foreach ($goodIps as $ip) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0/24”;
if (!isset($subnetMap[$subnet])) $subnetMap[$subnet] = 0;
$subnetMap[$subnet]++;
}
}
// Сортировка по количеству IP в диапазоне (убывание)
arsort($subnetMap);
// Выводим анализ
echo “=== WHITELIST /24 (с количеством IP в диапазоне) ===\n\n”;
foreach ($subnetMap as $subnet => $count) {
echo “$subnet → $count IP\n”;
}
echo “\nВсего диапазонов: ” . count($subnetMap) . “\n”;
echo “Общее количество IP: ” . array_sum($subnetMap) . “\n”;
// Генерация готового списка для push.house
echo “\n=== ГОТОВЫЙ СПИСОК ДЛЯ PUSH.HOUSE ===\n”;
foreach (array_keys($subnetMap) as $subnet) {
echo $subnet . “\n”;
}
🔹 Как пользоваться
Сохраняешь как
analyze_whitelist.phpрядом сips_good.txtиips_raw.txt.По желанию фильтруешь feed:
Запускаешь в браузере или CLI:
В выводе увидишь:
Сколько IP в каждом диапазоне
/24Общие stats
Готовый список для push.house
🔹 Что это дает
Быстро определяешь самые активные подсети
Можно решать, какие диапазоны использовать в whitelist
Сразу готовый для копирования
Фильтруешь по feed → экономишь деньги на низкокачественном трафике
3 финальная версия
Новый скрипт: top_whitelist_export.php
Даваем новую версию скрипта, полностью автономную, с выводом в файлы, чтобы предыдущие версии остались нетронутыми.
Генерирует два файла:
top_whitelist.txt→ для загрузки в push.housetop_whitelist_detailed.txt→ с количеством IP и feed для аналитики
Фильтр по feed опциональный
Минимальное количество IP в /24 настраивается
<?php
/*
Скрипт: top_whitelist_export.php
– Автоматически выделяет топ диапазоны /24
– Минимальное количество IP на диапазон
– Фильтрует по feed (sub2) при необходимости
– Генерирует два файла:
1) top_whitelist.txt (для push.house)
2) top_whitelist_detailed.txt (аналитика)
*/
// Файлы
$goodFile = ‘ips_good.txt’;
$rawFile = ‘ips_raw.txt’;
// Настройки
$filterFeed = []; // пример: [‘feed123′,’feed456’]; пустой = все feed
$minIpsInSubnet = 3; // минимальное количество IP в диапазоне, чтобы его использовать
// Выходные файлы
$outputWhitelist = ‘top_whitelist.txt’;
$outputDetailed = ‘top_whitelist_detailed.txt’;
// —————- Чтение IP —————-
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
// —————- Фильтр по feed —————-
if (!empty($filterFeed)) {
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$allowedIps = [];
foreach ($rawData as $line) {
if (preg_match(‘/sub2:([^\s|]+)/’, $line, $m)) {
$sub2 = $m[1];
if (in_array($sub2, $filterFeed)) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$allowedIps[] = $ipm[1];
}
}
}
}
$goodIps = array_intersect($goodIps, $allowedIps);
}
// —————- Группировка по /24 —————-
$subnetMap = [];
foreach ($goodIps as $ip) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0/24″;
if (!isset($subnetMap[$subnet])) $subnetMap[$subnet] = [‘count’=>0,’ips’=>[]];
$subnetMap[$subnet][‘count’]++;
$subnetMap[$subnet][‘ips’][] = $ip;
}
}
// —————- Оставляем только топ диапазоны —————-
$topSubnets = array_filter($subnetMap, function($data) use ($minIpsInSubnet) {
return $data[‘count’] >= $minIpsInSubnet;
});
// Сортировка по количеству IP (убывание)
uasort($topSubnets, function($a,$b){ return $b[‘count’] – $a[‘count’]; });
// —————- ВЫВОД —————-
$whitelistLines = [];
$detailedLines = [];
foreach ($topSubnets as $subnet => $data) {
$whitelistLines[] = $subnet;
$detailedLines[] = $subnet . ” → ” . $data[‘count’] . ” IP | ” . implode(‘, ‘, $data[‘ips’]);
}
// —————- СОХРАНЯЕМ В ФАЙЛЫ —————-
file_put_contents($outputWhitelist, implode(PHP_EOL, $whitelistLines));
file_put_contents($outputDetailed, implode(PHP_EOL, $detailedLines));
// —————- ОТЧЕТ —————-
echo “Файлы успешно созданы!\n”;
echo “Whitelist для push.house: $outputWhitelist\n”;
echo “Подробная аналитика: $outputDetailed\n”;
echo “Всего топ диапазонов: ” . count($topSubnets) . “\n”;
echo “Общее количество IP в топ диапазонах: ” . array_sum(array_column($topSubnets,’count’)) . “\n”;
🔹 Как использовать
Сохрани как
top_whitelist_export.phpНастрой фильтр feed, если нужно:
Задай минимальное количество IP в /24:
Запусти скрипт:
Результат:
top_whitelist.txt→ готовый для push.housetop_whitelist_detailed.txt→ аналитика по диапазонам и конкретным IP
🔹 Преимущества
Полностью автономно — предыдущие версии остаются нетронутыми
Можно использовать один скрипт для анализа и выгрузки
Фильтр по feed и минимальный порог — чистый whitelist
Легко повторять для новых данных через несколько дней
Новый скрипт: top_whitelist_export_ranges.php
Что он теперь делает:
Группирует IP по
/24Считает количество IP в диапазоне
Фильтрует диапазоны по порогу минимального числа IP
Считает количество IP по источнику (
sub3={site})Генерирует два файла:
top_whitelist_ranges.txt→ диапазоны для заливки в РК в формате185.55.13.0-185.55.13.255top_whitelist_detailed.txt→ аналитика с количеством IP и источником
<?php
/*
Скрипт: top_whitelist_export_ranges.php
– Группирует IP по /24
– Минимальное количество IP на диапазон
– Фильтрует по feed (sub2) при необходимости
– Выводит диапазоны для заливки в РК: x.x.x.0-x.x.x.255
– Указывает источник sub3 для аналитики
*/
// Файлы
$goodFile = ‘ips_good.txt’;
$rawFile = ‘ips_raw.txt’;
// Настройки
$filterFeed = []; // пример: [‘feed123′,’feed456’]; пустой = все feed
$minIpsInSubnet = 3; // минимальное количество IP в диапазоне
// Выходные файлы
$outputRanges = ‘top_whitelist_ranges.txt’;
$outputDetailed = ‘top_whitelist_detailed.txt’;
// —————- Чтение IP —————-
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
// —————- Чтение raw для sub3 и фильтра по feed —————-
$ipInfo = []; // ip => [‘sub3’=>…, ‘sub2’=>…]
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($rawData as $line) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$ip = $ipm[1];
if (!in_array($ip, $goodIps)) continue; // берем только хорошие IP
preg_match(‘/sub2:([^\s|]+)/’, $line, $f2);
preg_match(‘/sub3:([^\s|]+)/’, $line, $f3);
$ipInfo[$ip] = [
‘sub2’ => $f2[1] ?? ”,
‘sub3’ => $f3[1] ?? ”
];
}
}
// —————- Группировка по /24 —————-
$subnetMap = []; // subnet => [‘count’=>x, ‘ips’=>[], ‘sources’=>[]]
foreach ($ipInfo as $ip => $info) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0”;
if (!isset($subnetMap[$subnet])) $subnetMap[$subnet] = [‘count’=>0, ‘ips’=>[], ‘sources’=>[]];
$subnetMap[$subnet][‘count’]++;
$subnetMap[$subnet][‘ips’][] = $ip;
$subnetMap[$subnet][‘sources’][$info[‘sub3’]] = ($subnetMap[$subnet][‘sources’][$info[‘sub3’]] ?? 0) + 1;
}
}
// —————- Оставляем только диапазоны с >= minIpsInSubnet —————-
$topSubnets = array_filter($subnetMap, function($data) use ($minIpsInSubnet) {
return $data[‘count’] >= $minIpsInSubnet;
});
// Сортировка по количеству IP (убывание)
uasort($topSubnets, function($a,$b){ return $b[‘count’] – $a[‘count’]; });
// —————- Подготовка вывода —————-
$rangesLines = [];
$detailedLines = [];
foreach ($topSubnets as $subnet => $data) {
$range = $subnet . “-{$octets[0]}.{$octets[1]}.{$octets[2]}.255”; // x.x.x.0-x.x.x.255
$rangesLines[] = $range;
$sourcesInfo = [];
foreach ($data[‘sources’] as $src => $c) {
$sourcesInfo[] = “$src($c)”;
}
$detailedLines[] = “$range → {$data[‘count’]} IP | Sources: ” . implode(‘, ‘, $sourcesInfo) . ” | IPs: ” . implode(‘, ‘, $data[‘ips’]);
}
// —————- СОХРАНЕНИЕ —————-
file_put_contents($outputRanges, implode(PHP_EOL, $rangesLines));
file_put_contents($outputDetailed, implode(PHP_EOL, $detailedLines));
// —————- ОТЧЕТ —————-
echo “Файлы успешно созданы!\n”;
echo “Диапазоны для РК: $outputRanges\n”;
echo “Подробная аналитика: $outputDetailed\n”;
echo “Всего топ диапазонов: ” . count($topSubnets) . “\n”;
echo “Общее количество IP в топ диапазонах: ” . array_sum(array_column($topSubnets,’count’)) . “\n”;
🔹 Как использовать
Сохраняешь как
top_whitelist_export_ranges.phpрядом сips_good.txtиips_raw.txt.Настрой фильтр feed (если нужно):
Настрой порог минимального IP на диапазон:
Запускаешь:
Получаешь два файла:
top_whitelist_ranges.txt→ формат для заливки в РК, например:
top_whitelist_detailed.txt→ подробная аналитика:
Вот полная версия скрипта top_whitelist_export_ranges.php с поддержкой legacy IP, подсчётом по источникам (sub3) и генерацией диапазонов в формате x.x.x.0-x.x.x.255 для заливки в РК. Всё работает «в один клик».
<?php
/*
Скрипт: top_whitelist_export_ranges.php
– Автоматическое создание whitelist для push.house / РК
– Поддержка legacy IP (сверхценные)
– Группировка по /24
– Минимальный порог IP на диапазон
– Счётчик по источнику (sub3)
– Вывод:
1) top_whitelist_ranges.txt → диапазоны x.x.x.0-x.x.x.255 для РК
2) top_whitelist_detailed.txt → аналитика с IP и источниками
*/
// —————- НАСТРОЙКИ —————-
$goodFile = ‘ips_good.txt’; // новые хорошие IP
$rawFile = ‘ips_raw.txt’; // все переходы
$legacyFile = ‘ips_legacy.txt’; // «сверхценные» IP
$filterFeed = []; // пример: [‘feed123′,’feed456’]; пустой = все feed
$minIpsInSubnet = 3; // минимальное количество IP на диапазон
$outputRanges = ‘top_whitelist_ranges.txt’;
$outputDetailed = ‘top_whitelist_detailed.txt’;
// —————- 1️⃣ ЧТЕНИЕ ДАННЫХ —————-
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
// legacy IP
$legacyIps = file($legacyFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$legacyIps = array_map(‘trim’, $legacyIps);
// —————- 2️⃣ ЧТЕНИЕ RAW ДАННЫХ —————-
$ipInfo = []; // ip => [‘sub2’=>…, ‘sub3’=>…]
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($rawData as $line) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$ip = $ipm[1];
if (!in_array($ip, $goodIps)) continue; // только хорошие IP
preg_match(‘/sub2:([^\s|]+)/’, $line, $f2);
preg_match(‘/sub3:([^\s|]+)/’, $line, $f3);
// фильтр по feed, если указан
if (!empty($filterFeed) && !in_array($f2[1] ?? ”, $filterFeed)) continue;
$ipInfo[$ip] = [
‘sub2’ => $f2[1] ?? ”,
‘sub3’ => $f3[1] ?? ”
];
}
}
// —————- 3️⃣ ГРУППИРОВКА НОВЫХ IP ПО /24 —————-
$topSubnets = []; // subnet => [‘count’=>x,’ips’=>[],’sources’=>[]]
foreach ($ipInfo as $ip => $info) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0”;
if (!isset($topSubnets[$subnet])) $topSubnets[$subnet] = [‘count’=>0,’ips’=>[],’sources’=>[]];
$topSubnets[$subnet][‘count’]++;
$topSubnets[$subnet][‘ips’][] = $ip;
$topSubnets[$subnet][‘sources’][$info[‘sub3’]] = ($topSubnets[$subnet][‘sources’][$info[‘sub3’]] ?? 0) + 1;
}
}
// —————- 4️⃣ ДОБАВЛЕНИЕ LEGACY IP —————-
$legacySubnets = [];
foreach ($legacyIps as $ip) {
$octets = explode(‘.’, $ip);
if (count($octets) === 4) {
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0”;
if (!isset($legacySubnets[$subnet])) $legacySubnets[$subnet] = [‘count’=>0,’ips’=>[],’sources’=>[]];
$legacySubnets[$subnet][‘count’]++;
$legacySubnets[$subnet][‘ips’][] = $ip;
$legacySubnets[$subnet][‘sources’][‘legacy’] = ($legacySubnets[$subnet][‘sources’][‘legacy’] ?? 0) + 1;
}
}
// объединяем legacy и новые IP
foreach ($legacySubnets as $subnet => $data) {
if (!isset($topSubnets[$subnet])) {
$topSubnets[$subnet] = $data; // подтягиваем legacy диапазон в топ
} else {
// если диапазон уже есть, просто добавляем legacy IP
$topSubnets[$subnet][‘count’] += $data[‘count’];
$topSubnets[$subnet][‘ips’] = array_unique(array_merge($topSubnets[$subnet][‘ips’], $data[‘ips’]));
foreach ($data[‘sources’] as $src => $cnt) {
$topSubnets[$subnet][‘sources’][$src] = ($topSubnets[$subnet][‘sources’][$src] ?? 0) + $cnt;
}
}
}
// —————- 5️⃣ ФИЛЬТРАЦИЯ ПО MIN IP —————-
$topSubnets = array_filter($topSubnets, function($data) use ($minIpsInSubnet) {
return $data[‘count’] >= $minIpsInSubnet;
});
// —————- 6️⃣ СОРТИРОВКА —————-
uasort($topSubnets, function($a,$b){ return $b[‘count’] – $a[‘count’]; });
// —————- 7️⃣ ПОДГОТОВКА ВЫВОДА —————-
$rangesLines = [];
$detailedLines = [];
foreach ($topSubnets as $subnet => $data) {
$octets = explode(‘.’, $subnet);
$range = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0-{$octets[0]}.{$octets[1]}.{$octets[2]}.255”;
$rangesLines[] = $range;
$sourcesInfo = [];
foreach ($data[‘sources’] as $src => $c) {
$sourcesInfo[] = “$src($c)”;
}
$detailedLines[] = “$range → {$data[‘count’]} IP | Sources: ” . implode(‘, ‘, $sourcesInfo) . ” | IPs: ” . implode(‘, ‘, $data[‘ips’]);
}
// —————- 8️⃣ СОХРАНЕНИЕ ФАЙЛОВ —————-
file_put_contents($outputRanges, implode(PHP_EOL, $rangesLines));
file_put_contents($outputDetailed, implode(PHP_EOL, $detailedLines));
// —————- 9️⃣ ОТЧЕТ —————-
echo “Файлы успешно созданы!\n”;
echo “Диапазоны для РК: $outputRanges\n”;
echo “Подробная аналитика: $outputDetailed\n”;
echo “Всего топ диапазонов: ” . count($topSubnets) . “\n”;
echo “Общее количество IP в топ диапазонах: ” . array_sum(array_column($topSubnets,’count’)) . “\n”;
🔹 Особенности этой версии
Legacy IP гарантированно подтягивает свой /24 диапазон в топ, даже если новых IP мало.
Счётчик по источникам (sub3) + «legacy» → легко анализировать эффективность feed.
Диапазоны готовы для РК:
x.x.x.0-x.x.x.255Аналитика в отдельном файле: IP + источник + количество IP
1️⃣ Последовательность работы скриптов
Для твоей текущей системы с двухшаговым прелендом и логгером обычно так:
Собираем клики/заявки
Логи пишутся в
ips_raw.txt(все переходы с IP, feed, source, User-Agent)logger.phpформируетips_good.txtиbad_ips.txtпо правилам (тайминг, UA, повторные IP)
Запускаем скрипт формирования whitelist
top_whitelist_export_ranges.php(или предыдущую версию) берёт:ips_good.txt→ новые хорошие IPips_legacy.txt→ старые «сверхценные» IP
Группирует их по /24
Применяет минимальный порог (
$minIpsInSubnet)Генерирует файлы:
top_whitelist_ranges.txt→ диапазоны для РКtop_whitelist_detailed.txt→ аналитика по IP и источникам
✅ Результат: у тебя готовый whitelist после первых 300 кликов.
2️⃣ Что происходит, если пришло ещё 1000 кликов
Все новые клики логируются в
ips_raw.txtиips_good.txt(черезlogger.php)При повторном запуске скрипта
top_whitelist_export_ranges.php:Он читает полностью текущие файлы (
ips_good.txt,ips_legacy.txt)Генерирует новый whitelist заново с учётом всех данных
Старые файлы переписываются, а не добавляются к предыдущим результатам
Это означает, что предыдущие диапазоны могут исчезнуть, если теперь они не соответствуют порогу
3️⃣ Как избежать потери «ценных» диапазонов
Сохраняй legacy IP в отдельном файле (
ips_legacy.txt)Даже если новых IP в этом диапазоне мало, legacy IP гарантирует его попадание в whitelist
Сохраняй старый whitelist в резервную копию перед запуском скрипта
Например:
top_whitelist_ranges_backup_2026-01-14.txt
Запускай logger → скрипт формирования whitelist каждый раз, когда есть новые клики
4️⃣ Итоговая логика
Файлы
top_whitelist_ranges.txtиtop_whitelist_detailed.txtвсегда отражают текущее состояние, с учётом новых кликов и старых legacy IPЕсли не использовать legacy IP, старые «ценные» диапазоны могут пропасть, если теперь мало новых лидов
Повторный запуск не «ломает» файлы, просто переписывает их под актуальные данные
🔹 Рекомендованная последовательность действий после каждой партии кликов
Собираем клики (например, 300)
Запускаем
logger.php→ формируемips_good.txtиbad_ips.txtДобавляем в
ips_legacy.txtсвои «сверхценные» IP (если есть)Запускаем
top_whitelist_export_ranges.php→ формируем актуальный whitelistКопируем/сохраняем файл whitelist на будущее, если хочешь вернуться к предыдущей версии
Итог
| Файл | Формат | Ключевые атрибуты |
|---|---|---|
| ips_raw.txt | построчно | IP, sub2, sub3, UA, time |
| ips_good.txt | построчно | только IP |
| ips_legacy.txt | построчно | только IP |
| bad_ips.txt | построчно | IP, reason |
| top_whitelist_ranges.txt | построчно | x.x.x.0-x.x.x.255 |
| top_whitelist_detailed.txt | построчно | диапазон, кол-во IP, Sources, IPs |
Unix-права на файлы (chmod). 😎
600 → владелец чтение + запись, все остальные — нет доступа
Формально:
rw-------Безопасно для хранения IP и логов, никто кроме владельца не сможет читать/писать
666 → все пользователи чтение + запись, но нет выполнения
Формально:
rw-rw-rw-Не безопасно: любой пользователь/процесс на сервере сможет читать и изменять файлы
🔹 Что выбрать для логов и whitelist
| Файл | Рекомендация |
|---|---|
| ips_raw.txt | 600 — содержит все переходы, может быть чувствительно |
| ips_good.txt | 600 — хорошие IP, тоже внутренние данные |
| ips_legacy.txt | 600 — «сверхценные» IP, не для посторонних |
| bad_ips.txt | 600 — тоже внутренние данные |
| top_whitelist_ranges.txt | 644 — если нужно давать доступ РК или другим сервисам |
| top_whitelist_detailed.txt | 644 — аналитика, можно читать, но не обязательно писать всем |
В целом, для логов 600 будет безопаснее, для файлов, которыми нужно делиться — 644.
PHP‑файлы (index.php, logger.php, top_whitelist_export_ranges.php)
✅ Правильные права
644
То есть:
владелец – читать + писать
веб‑сервер (Apache / nginx / php‑fpm) – читать
выполнение не нужно (PHP исполняется интерпретатором)
👉 755 для PHP не требуется, это распространённая ошибка.
📌 Рекомендованная таблица прав
| Тип файла | Пример | chmod |
|---|---|---|
| PHP‑скрипты | index.php, logger.php | 644 |
| Логи / IP‑листы | ips_raw.txt, ips_good.txt, bad_ips.txt | 600 |
| Legacy IP | ips_legacy.txt | 600 |
| Готовые whitelist | top_whitelist_ranges.txt | 644 |
| Аналитика | top_whitelist_detailed.txt | 644 |
📂 Папки
Для каталогов:
Папка должна быть:
доступна на чтение серверу
доступна на запись владельцу
⚠️ Частые ошибки
❌ 777 — никогда не надо, опасно
❌ 666 — может сломать безопасность
❌ 600 для PHP — сервер не сможет читать файл
✅ Идеальная команда (разово)
💡 Короткий вывод
PHP = 644
логи = 600
папки = 755
никаких 777
финальная версия скрипта top_whitelist_export_ranges.php, которая сразу делает всё, как ты просил:
Использует новые хорошие IP (
ips_good.txt)Учитывает legacy IP (
ips_legacy.txt) для подтягивания диапазоновУчитывает legacy site (
site_legacy.txt) для подтягивания источниковГенерирует три файла:
top_whitelist_ranges.txt— только диапазоны хороших IP/24top_whitelist_ranges2.txt— только хорошие источники (sub3) + legacy sitetop_whitelist_detailed.txt— полная аналитика с IP, источниками и Legacy-флагом
<?php
/*
Финальная версия top_whitelist_export_ranges.php
– Учитывает новые хорошие IP и legacy IP
– Учитывает legacy site
– Генерирует 3 файла:
1) top_whitelist_ranges.txt -> диапазоны хороших IP
2) top_whitelist_ranges2.txt -> хорошие источники + legacy site
3) top_whitelist_detailed.txt -> аналитика
*/
// —————- НАСТРОЙКИ —————-
$goodFile = ‘ips_good.txt’; // новые хорошие IP
$rawFile = ‘ips_raw.txt’; // все переходы
$legacyIPFile = ‘ips_legacy.txt’; // legacy IP
$legacySiteFile = ‘site_legacy.txt’; // legacy site
$minIpsInSubnet = 3; // минимальное количество IP на диапазон
$outputRanges = ‘top_whitelist_ranges.txt’;
$outputSources = ‘top_whitelist_ranges2.txt’;
$outputDetailed = ‘top_whitelist_detailed.txt’;
// —————- 1️⃣ ЧТЕНИЕ ДАННЫХ —————-
$goodIps = file($goodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$goodIps = array_map(‘trim’, $goodIps);
$legacyIps = file($legacyIPFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$legacyIps = array_map(‘trim’, $legacyIps);
$legacySites = file($legacySiteFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$legacySites = array_map(‘trim’, $legacySites);
// —————- 2️⃣ ЧТЕНИЕ RAW ДАННЫХ —————-
$ipInfo = []; // ip => [‘sub2’=>…, ‘sub3’=>…]
$rawData = file($rawFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($rawData as $line) {
if (preg_match(‘/IP:([0-9.]+)/’, $line, $ipm)) {
$ip = $ipm[1];
if (!in_array($ip, $goodIps)) continue; // только хорошие IP
preg_match(‘/sub2:([^\s|]+)/’, $line, $f2);
preg_match(‘/sub3:([^\s|]+)/’, $line, $f3);
$ipInfo[$ip] = [
‘sub2’ => $f2[1] ?? ”,
‘sub3’ => $f3[1] ?? ”
];
}
}
// —————- 3️⃣ ГРУППИРОВКА НОВЫХ IP ПО /24 —————-
$topSubnets = []; // subnet => [‘count’=>x,’ips’=>[],’sources’=>[],’legacy’=>false]
foreach ($ipInfo as $ip => $info) {
$octets = explode(‘.’, $ip);
if(count($octets) !== 4) continue;
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0”;
if (!isset($topSubnets[$subnet])) $topSubnets[$subnet] = [‘count’=>0,’ips’=>[],’sources’=>[],’legacy’=>false];
$topSubnets[$subnet][‘count’]++;
$topSubnets[$subnet][‘ips’][] = $ip;
$topSubnets[$subnet][‘sources’][$info[‘sub3’]] = ($topSubnets[$subnet][‘sources’][$info[‘sub3’]] ?? 0) + 1;
// если sub3 в legacySites → помечаем диапазон как legacy
if (in_array($info[‘sub3’], $legacySites)) {
$topSubnets[$subnet][‘legacy’] = true;
}
}
// —————- 4️⃣ ДОБАВЛЕНИЕ LEGACY IP —————-
$legacySubnets = [];
foreach ($legacyIps as $ip) {
$octets = explode(‘.’, $ip);
if(count($octets) !== 4) continue;
$subnet = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0”;
if (!isset($legacySubnets[$subnet])) $legacySubnets[$subnet] = [‘count’=>0,’ips’=>[],’sources’=>[],’legacy’=>true];
$legacySubnets[$subnet][‘count’]++;
$legacySubnets[$subnet][‘ips’][] = $ip;
$legacySubnets[$subnet][‘sources’][‘legacy’] = ($legacySubnets[$subnet][‘sources’][‘legacy’] ?? 0) + 1;
}
// объединяем legacy и новые IP
foreach ($legacySubnets as $subnet => $data) {
if (!isset($topSubnets[$subnet])) {
$topSubnets[$subnet] = $data;
} else {
$topSubnets[$subnet][‘count’] += $data[‘count’];
$topSubnets[$subnet][‘ips’] = array_unique(array_merge($topSubnets[$subnet][‘ips’], $data[‘ips’]));
foreach($data[‘sources’] as $src => $cnt) {
$topSubnets[$subnet][‘sources’][$src] = ($topSubnets[$subnet][‘sources’][$src] ?? 0) + $cnt;
}
$topSubnets[$subnet][‘legacy’] = true;
}
}
// —————- 5️⃣ ФИЛЬТРАЦИЯ ПО MIN IP —————-
$topSubnets = array_filter($topSubnets, function($data) use ($minIpsInSubnet) {
return $data[‘count’] >= $minIpsInSubnet;
});
// —————- 6️⃣ СОРТИРОВКА —————-
uasort($topSubnets, function($a,$b){ return $b[‘count’] – $a[‘count’]; });
// —————- 7️⃣ ФОРМИРОВАНИЕ top_whitelist_ranges.txt —————-
$rangesLines = [];
foreach ($topSubnets as $subnet => $data) {
$octets = explode(‘.’, $subnet);
$range = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0-{$octets[0]}.{$octets[1]}.{$octets[2]}.255”;
$rangesLines[] = $range;
}
file_put_contents($outputRanges, implode(PHP_EOL, $rangesLines));
// —————- 8️⃣ ФОРМИРОВАНИЕ top_whitelist_ranges2.txt (источники) —————-
$goodSources = [];
foreach ($topSubnets as $subnet => $data) {
foreach ($data[‘sources’] as $src => $cnt) {
$goodSources[$src] = true;
}
}
foreach ($legacySites as $site) {
$goodSources[$site] = true;
}
file_put_contents($outputSources, implode(PHP_EOL, array_keys($goodSources)));
// —————- 9️⃣ ФОРМИРОВАНИЕ top_whitelist_detailed.txt —————-
$detailedLines = [];
foreach ($topSubnets as $subnet => $data) {
$octets = explode(‘.’, $subnet);
$range = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0-{$octets[0]}.{$octets[1]}.{$octets[2]}.255”;
$sourcesInfo = [];
foreach ($data[‘sources’] as $src => $c) {
$sourcesInfo[] = “$src($c)”;
}
$legacyFlag = ($data[‘legacy’] ?? false) ? ‘yes’ : ‘no’;
$detailedLines[] = “$range → {$data[‘count’]} IP | Sources: ” . implode(‘, ‘, $sourcesInfo) . ” | IPs: ” . implode(‘, ‘, $data[‘ips’]) . ” | Legacy: $legacyFlag”;
}
file_put_contents($outputDetailed, implode(PHP_EOL, $detailedLines));
// —————- 10️⃣ ОТЧЕТ —————-
echo “Файлы успешно созданы!\n”;
echo “Диапазоны для РК: $outputRanges\n”;
echo “Источники: $outputSources\n”;
echo “Подробная аналитика: $outputDetailed\n”;
echo “Всего топ диапазонов: ” . count($topSubnets) . “\n”;
echo “Общее количество IP в топ диапазонах: ” . array_sum(array_column($topSubnets,’count’)) . “\n”;
🔹 Рекомендованная последовательность действий после каждой партии кликов
Собираем клики (например, 300)
Запускаем
logger.php→ формируемips_good.txtиbad_ips.txtДобавляем в
ips_legacy.txtсвои «сверхценные» IP (если есть)Запускаем
top_whitelist_export_ranges.php→ формируем актуальный whitelistКопируем/сохраняем файл whitelist на будущее, если хочешь вернуться к предыдущей версии
финальную версию logger.php, которая учитывает все наши пожелания:
Двухшаговый преленд (логируем после второго шага)
Проверка тайминга между шагами (например, минимум 900 мс)
Фильтр по User-Agent (отбрасываем ботов)
Фильтр повторных IP (не более 3 раз)
Разделение на:
ips_raw.txt— все переходыips_good.txt— только хорошие IPbad_ips.txt— «плохие» IP (UA, тайминг, частота)
Группировка в
/24диапазоны и запись вips_good_ranges.txtчерез дефис
<?php
/*
logger.php – финальная версия
Логирует клики с преленда после второго шага
Проверка тайминга, User-Agent, повторов
Формирует файлы:
– ips_raw.txt -> все переходы
– ips_good.txt -> хорошие IP
– ips_good_ranges.txt -> /24 диапазоны хороших IP
– bad_ips.txt -> плохие IP с причиной
*/
date_default_timezone_set(‘UTC’); // таймзона для логов
// —————- НАСТРОЙКИ —————-
$ipsRawFile = ‘ips_raw.txt’;
$ipsGoodFile = ‘ips_good.txt’;
$ipsGoodRangeFile= ‘ips_good_ranges.txt’;
$badIpsFile = ‘bad_ips.txt’;
$minStepTimeMs = 900; // минимальный тайминг между шагами
$maxRepeat = 3; // макс. повтор IP в good list
$botUAPatterns = [‘/bot/i’, ‘/spider/i’, ‘/crawl/i’, ‘/curl/i’, ‘/wget/i’];
// —————- 1️⃣ ПОЛУЧАЕМ ДАННЫЕ —————-
$ip = $_SERVER[‘REMOTE_ADDR’] ?? ‘0.0.0.0’;
$ua = $_SERVER[‘HTTP_USER_AGENT’] ?? ‘unknown’;
$sub2 = $_GET[‘sub2’] ?? ”;
$sub3 = $_GET[‘sub3’] ?? ”;
$step1 = $_GET[‘step1_time’] ?? 0; // передаём тайминг с преленда
$step2 = microtime(true) * 1000; // сейчас в мс
$delta = $step2 – floatval($step1);
// —————- 2️⃣ ЧИСТИМ БОТОВ —————-
$isBot = false;
foreach ($botUAPatterns as $pattern) {
if (preg_match($pattern, $ua)) {
$isBot = true;
break;
}
}
// —————- 3️⃣ ЧТО ПИСАТЬ В ПЛОХИЕ —————-
$reason = ”;
if ($delta < $minStepTimeMs) $reason = ‘fast_click’;
if ($isBot) $reason = $reason ? $reason.’,bad_ua’ : ‘bad_ua’;
// —————- 4️⃣ ЛОГИРУЕМ ВСЕ IP —————-
$rawLine = “IP:$ip | sub2:$sub2 | sub3:$sub3 | UA:$ua | time:”.time();
file_put_contents($ipsRawFile, $rawLine.PHP_EOL, FILE_APPEND);
// —————- 5️⃣ ЛОГИРУЕМ ПЛОХИЕ —————-
if ($reason) {
file_put_contents($badIpsFile, “IP:$ip | reason:$reason”.PHP_EOL, FILE_APPEND);
exit; // дальше не идём
}
// —————- 6️⃣ ФИЛЬТР ПОВТОРОВ —————-
$goodIps = file($ipsGoodFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$countIp = count(array_filter($goodIps, fn($v)=>trim($v)==$ip));
if ($countIp >= $maxRepeat) {
file_put_contents($badIpsFile, “IP:$ip | reason:too_many”.PHP_EOL, FILE_APPEND);
exit;
}
// —————- 7️⃣ ЗАПИСЬ ХОРОШИХ IP —————-
file_put_contents($ipsGoodFile, $ip.PHP_EOL, FILE_APPEND);
// —————- 8️⃣ СОЗДАНИЕ /24 ДИАПАЗОНА —————-
$octets = explode(‘.’, $ip);
if(count($octets) === 4){
$range = “{$octets[0]}.{$octets[1]}.{$octets[2]}.0-{$octets[0]}.{$octets[1]}.{$octets[2]}.255”;
$existingRanges = file_exists($ipsGoodRangeFile) ? file($ipsGoodRangeFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) : [];
if(!in_array($range, $existingRanges)){
file_put_contents($ipsGoodRangeFile, $range.PHP_EOL, FILE_APPEND);
}
}
// —————- 9️⃣ ОТЧЕТ —————-
echo “logged: $ip | delta: {$delta}ms | reason: “.($reason ?: ‘good’);
Вот финальный top_whitelist_export_ranges_final.php, полностью совместимый с последним logger.php и preland, с учётом всех наших улучшений: Legacy IP, Legacy Sites, фильтрация bad IP, готовый формат для Push.house.
✅ top_whitelist_export_ranges_final.php
🔹 Что делает этот скрипт
Берёт ips_good.txt и sites_good.txt.
Фильтрует bad_ips.txt, чтобы не попадали в whitelist.
Объединяет legacy IP и legacy Sites.
Уникальные записи → дубли не повторяются.
Формат IP
/24уже из logger.php (185.55.13.0-185.55.13.255).Создаёт два файла:
top_whitelist_ranges.txt→ для Push.house IPtop_whitelist_ranges2.txt→ для Sources (sub3)
Выводит отчёт в консоль о количестве IP и источников.
💡 Использование:
После запуска получаешь готовые файлы для Push.house: IP + sub3
Можно запускать каждый раз после новых кликов, они объединяют старые данные (legacy) и новые, фильтруют bad IP.
готовый «workflow» для твоих пушей:
preland_push.php (старый, модерация) → step2_click
logger.php → step2, legacy, bad IP
top_whitelist_export_ranges_final.php → готовый whitelist
Так ты будешь «собирать все хорошие IP и источники автоматически» без ручного труда.
Nmu2.ru
стимуляции сокодвижения), так и побег розы.