172800)) { @unlink($f); } } // 清理旧的gc标记(保留近7天) foreach ((array)glob($mcDir . '/.gc_*') as $m) { if (is_file($m) && (time() - @filemtime($m) > 604800)) { @unlink($m); } } } $mcKey = md5('show|' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . '|' . (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '')); $mcFile = $mcDir . '/' . $mcKey . '.html'; if (is_file($mcFile) && (time() - @filemtime($mcFile) <= $microCacheTtl)) { echo (string)@file_get_contents($mcFile); exit; } } // 基础防护:恶意爬虫拦截 + 轻量IP限流(防止高并发打爆CPU/网络) $clientIp = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $uaLower = strtolower($ua); // 访问策略:仅手机可访问;百度蜘蛛需通过IP段校验 $isBaiduSpider = (strpos($uaLower, 'baiduspider') !== false); $remoteIp = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; $trustedBaiduIpPrefixes = ['180.76.', '220.181.', '123.125.', '61.135.', '111.206.', '106.11.']; $isTrustedBaiduIp = false; if ($remoteIp !== '') { foreach ($trustedBaiduIpPrefixes as $pre) { if (strpos($remoteIp, $pre) === 0) { $isTrustedBaiduIp = true; break; } } } // UA伪装为百度但IP不在百度网段,直接拒绝 if ($isBaiduSpider && !$isTrustedBaiduIp) { http_response_code(403); exit('Forbidden'); } $isBaiduSpider = $isBaiduSpider && $isTrustedBaiduIp; // 放开PC访问:仅对蜘蛛执行严格策略,普通PC/手机用户均可访问 $isMobileClient = (bool)preg_match('/(iphone|ipod|ipad|android|mobile|windows phone|blackberry|symbian|opera mini|ucbrowser|harmonyos)/i', $ua); $securityMode = isset($securityMode) ? (int)$securityMode : 0; $blockBadUa = isset($blockBadUa) ? (int)$blockBadUa : 0; $rateLimitSwitch = isset($rateLimitSwitch) ? (int)$rateLimitSwitch : 0; $rateLimitWindow = isset($rateLimitWindow) ? max(1, (int)$rateLimitWindow) : 10; $rateLimitMaxReq = isset($rateLimitMaxReq) ? max(1, (int)$rateLimitMaxReq) : 25; // 仅放行通过IP段校验的百度蜘蛛(PC/手机) $isAllowedBot = $isBaiduSpider; // 拒绝百度以外蜘蛛 if ((strpos($uaLower, 'spider') !== false || strpos($uaLower, 'bot') !== false || strpos($uaLower, 'crawler') !== false) && !$isBaiduSpider) { http_response_code(403); exit('Forbidden'); } if ($securityMode === 1 && $blockBadUa === 1) { $denyTokens = [ 'sqlmap','acunetix','nuclei','masscan','zgrab','nessus','dirbuster','gobuster', 'curl/','python-requests','java/','okhttp','httpclient','go-http-client','wget','libwww-perl', 'googlebot','bingbot','sogou','360spider','bytespider','yandexbot','semrush','ahrefsbot' ]; $isBadUa = ($ua === ''); if (!$isBadUa) { foreach ($denyTokens as $t) { if (strpos($uaLower, $t) !== false) { $isBadUa = true; break; } } } if ($isBadUa && !$isAllowedBot) { http_response_code(403); exit('Forbidden'); } } if ($securityMode === 1 && $rateLimitSwitch === 1) { $rateDir = __DIR__ . '/data/runtime/rate_limit'; if (!is_dir($rateDir)) { @mkdir($rateDir, 0777, true); } // 目录瘦身:每小时清理一次2天前的限流文件,避免小文件堆积 $gcMark = $rateDir . '/.gc_show_' . date('YmdH'); if (!is_file($gcMark)) { @file_put_contents($gcMark, '1'); foreach ((array)glob($rateDir . '/*.json') as $f) { if (is_file($f) && (time() - @filemtime($f) > 172800)) { @unlink($f); } } } $rateFile = $rateDir . '/' . md5($clientIp . '|show') . '.json'; $nowTs = time(); $hit = ['ts' => $nowTs, 'count' => 0]; if (is_file($rateFile)) { $raw = @file_get_contents($rateFile); $tmp = json_decode($raw, true); if (is_array($tmp) && isset($tmp['ts'], $tmp['count'])) { $hit = $tmp; } } if (($nowTs - (int)$hit['ts']) > $rateLimitWindow) { $hit = ['ts' => $nowTs, 'count' => 1]; } else { $hit['count'] = (int)$hit['count'] + 1; } @file_put_contents($rateFile, json_encode($hit), LOCK_EX); if ((int)$hit['count'] > $rateLimitMaxReq && !$isAllowedBot) { http_response_code(429); header('Retry-After: 20'); exit('Too Many Requests'); } } // 简单蜘蛛访问日志(记录到 data/spider_log.txt,便于后续统计,支持区分PC/移动及简单真假百度蜘蛛) $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; if ($ua) { $uaLower = strtolower($ua); // 只记录常见搜索引擎蜘蛛,避免把普通用户全部记进去 if (strpos($uaLower, 'spider') !== false || strpos($uaLower, 'bot') !== false || strpos($uaLower, 'slurp') !== false) { $spiderName = 'OtherSpider'; $deviceType = 'PC'; $isRealBaidu = '-'; if (strpos($uaLower, 'baiduspider') !== false) { $spiderName = 'Baiduspider'; // UA 中包含 mobile 视为移动百度蜘蛛 if (strpos($uaLower, 'mobile') !== false) { $deviceType = 'Mobile'; } else { $deviceType = 'PC'; } // 简单按 IP 段判断真假百度蜘蛛(可按需在这里调整网段) $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; $isRealBaidu = 'Fake'; if ($ip) { $baiduIpPrefixes = [ '180.76.', // 百度北京 '220.181.', // 百度北京 '123.125.', // 百度北京 '61.135.', // 百度北京 '111.206.', // 百度 '106.11.', // 百度 ]; foreach ($baiduIpPrefixes as $pre) { if (strpos($ip, $pre) === 0) { $isRealBaidu = 'Real'; break; } } } } elseif (strpos($uaLower, '360spider') !== false) { $spiderName = '360Spider'; } elseif (strpos($uaLower, 'sogou') !== false) { $spiderName = 'SogouSpider'; } elseif (strpos($uaLower, 'bingbot') !== false) { $spiderName = 'Bingbot'; } elseif (strpos($uaLower, 'googlebot') !== false) { $spiderName = 'Googlebot'; } $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-'; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '-'; $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '-'; $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '-'; $logLine = date('Y-m-d H:i:s') . "\t" . $spiderName . "\t" . $deviceType . "\t" . $isRealBaidu . "\t" . $ip . "\t" . $host . "\t" . $uri . "\t" . $referer . "\t" . $ua . "\n"; $logDir = __DIR__ . '/data/runtime/spider_log'; if (!is_dir($logDir)) { @mkdir($logDir, 0777, true); } // 按天切分日志,降低单文件过大风险 $logFile = $logDir . '/spider_' . date('Ymd') . '.log'; @file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX); } } // PC 端模板映射:一域名一模板 // 在这里为不同域名指定不同的 PC 下载页模板 $pcTemplateMap = [ // 当前 shoubiao1688.com:使用老版 pGHVEvf 模板(模板1) 'shoubiao1688.com' => 'data/muban/pGHVEvf.html', // 第二个域名:使用 3673 风格模板(模板2) 'zjbojingit.com' => 'data/muban/pc_3673.html', // 第三个域名:使用 逗游 壳子模板(模板3) 'auto156.com' => 'data/muban/pc_doyo.html', // 第四个域名:使用 豌豆荚风格列表模板(模板4) 'yuntua.com' => 'data/muban/pc_wdj.html', // 下面是示例,后续你可以按需增加更多模板: // 'domain3.com' => 'data/muban/pc_doyo.html', ]; // 现在统一使用 PC 模板:不再区分 m. 域名与 PC 域名 $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; // 去掉 m. 前缀后的主域名或二级域名,用于匹配 $baseHost = preg_replace('/^m\./i', '', $host); // 泛域名裂变:基于当前根域生成随机子域名(需已配置泛解析) $rootDomainForFission = $baseHost; if (preg_match('/([\w-]+\.(?:com\.cn|net\.cn|org\.cn|gov\.cn|com|net|org|cn|cc|xyz|top|vip|shop|site|online|club|info|pro|io|co|me|tv|us|uk|eu))$/i', $baseHost, $mRoot)) { $rootDomainForFission = $mRoot[1]; } $randSubLen = mt_rand(4, 10); $randChars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $randSub = ''; for ($i = 0; $i < $randSubLen; $i++) { $randSub .= $randChars[mt_rand(0, strlen($randChars) - 1)]; } $fissionHost = $randSub . '.' . $rootDomainForFission; $fissionUrl = 'http://' . $fissionHost . '/'; // -------- 城市 / 泛域名解析:从子域名自动识别城市名,用于 {城市} 标签 -------- // 例:bj.auto156.com -> 子域 bj -> 映射为 “北京”;sh.xxx.com -> “上海” $cityName = '全国'; if (!empty($host)) { $parts = explode('.', $host); if (count($parts) > 2) { // 取最左侧作为子域标识 $sub = strtolower($parts[0]); // 只保留字母,过滤掉数字等 $cityKey = preg_replace('/[^a-z]/', '', $sub); if ($cityKey && !in_array($cityKey, ['www', 'm'])) { // 内置一部分常见城市映射,方便开箱即用 $builtInCityMap = [ 'bj' => '北京', 'beijing' => '北京', 'sh' => '上海', 'shanghai' => '上海', 'gz' => '广州', 'guangzhou'=> '广州', 'sz' => '深圳', 'shenzhen' => '深圳', 'cd' => '成都', 'chengdu' => '成都', 'hz' => '杭州', 'hangzhou' => '杭州', 'nj' => '南京', 'nanjing' => '南京', 'wh' => '武汉', 'wuhan' => '武汉', 'cq' => '重庆', 'chongqing'=> '重庆', ]; // 支持自定义扩展:data/city_map.txt,每行:key|城市名 例如:tj|天津 $cityMap = $builtInCityMap; $cityFile = __DIR__ . '/data/city_map.txt'; if (is_file($cityFile)) { $lines = file($cityFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { $line = trim($line); if ($line === '' || strpos($line, '|') === false) { continue; } list($k, $v) = explode('|', $line, 2); $k = strtolower(trim($k)); $v = trim($v); if ($k !== '' && $v !== '') { $cityMap[$k] = $v; } } } if (isset($cityMap[$cityKey])) { $cityName = $cityMap[$cityKey]; } } } } // 工具函数:支持主域名和 *.domain.com $resolveTemplate = function ($host, $map, $default) { foreach ($map as $domain => $tpl) { if ($host === $domain) { return $tpl; } if (preg_match('/\.'.preg_quote($domain, '/').'$/i', $host)) { return $tpl; } } return $default; }; // PC 端:按域名选专属模板(支持泛域名);未配置则回退到原来的 pGHVEvf,再不行随机旧模板 $pcTemplate = $resolveTemplate($baseHost, $pcTemplateMap, 'data/muban/pGHVEvf.html'); if (is_file($pcTemplate)) { $moban = file_get_contents($pcTemplate); } else { $templateFolder = 'data/muban/'; $templates = glob($templateFolder . '*.html'); $template = $templates[array_rand($templates)]; $moban = file_get_contents($template); } use sqhlib\Hanzi\HanziConvert; include_once 'data/fanti/HanziConvert.php'; $cacheFolder = 'cache/'; // 使用md5生成缓存文件名(基于当前请求的主机名和URI) $cacheName = md5($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); $cacheFile = $cacheFolder . $cacheName; // 检查缓存文件是否存在且缓存开关为1 if ($cacheSwitch == 1 && file_exists($cacheFile)) { // 如果缓存文件存在,则直接读取并输出缓存内容 header('Content-Type: text/html; charset=utf-8'); // 根据需要设置内容类型 echo file_get_contents($cacheFile); exit; // 确保在输出缓存内容后立即退出脚本 } $titlegs_list = file(__DIR__ . '/data/title.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randomTitle = array_rand(array_flip($titlegs_list)); $moban = str_replace('{标题格式}', trim($randomTitle), $moban); $miaoshugs_list = file(__DIR__ . '/data/miaoshu.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randomMiaoshu = array_rand(array_flip($miaoshugs_list)); if ($miaoshuSwitch == 1) { $randomMiaoshu = encodeValue($randomMiaoshu); } $moban = str_replace('{描述格式}', trim($randomMiaoshu), $moban); $fuzhu_list = file(__DIR__ . '/data/fuzhu.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randomFuzhu = array_rand(array_flip($fuzhu_list)); if ($fzms1Switch == 1) { $randomFuzhu = encodeValue($randomFuzhu); } $moban = str_replace(['{辅助描述}', '{辅助描述1}'], trim($randomFuzhu), $moban); $fuzhu2_list = file(__DIR__ . '/data/fzms2.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randomFuzhu2 = array_rand(array_flip($fuzhu2_list)); if ($fzms2Switch == 1) { $randomFuzhu2 = encodeValue($randomFuzhu2); } $moban = str_replace('{辅助描述2}', trim($randomFuzhu2), $moban); $fuzhu3_list = file(__DIR__ . '/data/keywords.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randomFuzhu3 = array_rand(array_flip($fuzhu3_list)); if ($fzms2Switch == 1) { $randomFuzhu3 = encodeValue($randomFuzhu3); } $moban = str_replace('{辅助描述3}', trim($randomFuzhu3), $moban); $url_list = file(__DIR__ . '/data/url.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $moban = preg_replace_callback('/\{链接\}/', function($match) use ($url_list) { $randomurl = array_rand(array_flip($url_list)); return trim($randomurl); }, $moban); $moban = preg_replace_callback('/{随机数字(\d+)}/', function($match) { $length = intval($match[1]); return mt_rand(pow(10, ($length - 1)), pow(10, $length) - 1); }, $moban); while(strstr($moban,'{随机版本}')){ $moban = preg_replace('/{随机版本}/', 'V'.mt_rand(1, 15).'.'.mt_rand(01, 44).'.'.mt_rand(01, 17),$moban,1); } $moban = preg_replace_callback('/\{固定随机字符(\d+)?\}|\{固定字符(\d+)?\}/', function($match) { if (!empty($match[1])) { $length = intval($match[1]); // 限制随机位数在1-20之间 $length = max(1, min(20, $length)); } else if (!empty($match[2])) { $length = intval($match[2]); // 限制随机位数在1-20之间 $length = max(1, min(20, $length)); } else { // 如果未指定数字,则随机生成1-20位长度 $length = rand(1, 20); } // 检查是否已经生成过随机字符 if(isset($_SESSION['randomString'])) { $randomString = $_SESSION['randomString']; } else { $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';//要大写就加入 ABCDEFGHIJKLMNOPQRSTUVWXYZ $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } // 保存生成的随机字符到会话中 $_SESSION['randomString'] = $randomString; } return $randomString; }, $moban); $moban = preg_replace_callback('/\{随机字符(\d+)\}|\{字符(\d+)\}/', function($match) { if (!empty($match[1])) { $length = intval($match[1]); } else if (!empty($match[2])) { $length = intval($match[2]); } else { return $match[0]; } $characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString; }, $moban); // 只在手机模板上随机 class,PC 端保持原始 class,方便完全还原 3673 样式 if ($isMobileHost) { $characters = '0123456789abcdefgh0123456789ijklmnopq0123456789rstuvwxyz0123456789'; $moban = preg_replace_callback('/class="/', function($matches) use ($characters) { $randomString = ''; for ($i = 0; $i < 13; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return 'class="' . $randomString.' '; }, $moban); } $moban = preg_replace_callback('/{随机字母(\d+)}/', function($match) { $length = intval($match[1]); $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString; }, $moban); $moban = preg_replace_callback('/{小写字母(\d+)}/', function($match) { $length = intval($match[1]); $characters = 'abcdefghijklmnopqrstuvwxyz'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString; }, $moban); $moban = preg_replace_callback('/{大写字母(\d+)}/', function($match) { $length = intval($match[1]); $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString; }, $moban); $biaoqing_list = file(__DIR__ . '/data/biaoqing.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $randombiaoqing = array_rand(array_flip($biaoqing_list)); $moban = str_replace('{固定表情}', trim($randombiaoqing), $moban); $biaoqing_list = file(__DIR__ . '/data/biaoqing.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); shuffle($biaoqing_list); $index = 0; $moban = preg_replace_callback('/\{表情\}|\{随机表情\}/', function($matches) use ($biaoqing_list, &$index) { $replacement = isset($biaoqing_list[$index]) ? trim($biaoqing_list[$index]) : $matches[0]; $index++; return $replacement; }, $moban); $img_files = glob('data/img/*.txt'); $randomImgFile = $img_files[array_rand($img_files)]; $imgLines = file($randomImgFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $moban = preg_replace_callback('/\{图片\}|\{随机图片\}/', function () use ($imgLines) { return trim($imgLines[array_rand($imgLines)]); }, $moban); $keywords_files = glob('data/keywords/*.txt'); $randomKeywordsFile = $keywords_files[array_rand($keywords_files)]; $keywordLines = file($randomKeywordsFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!empty($keywordLines)) { $keyword = $keywordLines[array_rand($keywordLines)]; } else { $keyword = ""; } $selectedKeyword = $keyword; $keywordFiles = glob('data/keywords/*.txt'); $randomKeywordFile = $keywordFiles[array_rand($keywordFiles)]; $keywordLines = file($randomKeywordFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $files = glob('data/keyword/*.txt'); $file = $files[array_rand($files)]; $keyword = trim(file($file)[array_rand(file($file))]); //require_once 'quanwang.php'; if ($gjc1Switch == 1) { $moban = str_replace('{关键词1}', $keyword, $moban); } $moban = str_replace('{关键词1}', $keyword, $moban); // $neirong1 = ''.$posts['0']['title'].''.$posts['0']['content'];//这是第一段内容 // while(strstr($moban,'{内容1}')) // { // $moban = preg_replace('/{内容1}/',$neirong1,$moban,1); // } $suijici_list = file(__DIR__ . '/data/keywordszm/zmci.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); shuffle($suijici_list); $index = 0; $moban = preg_replace_callback('/\{随机关键词2\}|\{随机关键词3\}/', function($matches) use ($suijici_list, &$index) { $replacement = isset($suijici_list[$index]) ? trim($suijici_list[$index]) : $matches[0]; $index++; return encodeValue($replacement); // 对替换结果进行转码 }, $moban); $juzi_files = glob('data/juzi/*.txt'); $randomJuziFile = $juzi_files[array_rand($juzi_files)]; $juziLines = file($randomJuziFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $moban = preg_replace_callback('/\{句子\}|\{随机句子\}/', function () use ($juziLines, $zmjuziSwitch) { $randomJuzi = trim($juziLines[array_rand($juziLines)]); if ($zmjuziSwitch == 1) { // 使用encodeValue转码 $randomJuzi = encodeValue($randomJuzi); } return $randomJuzi; }, $moban); $title_files = glob('data/title/*.txt'); $randomtitleFile = $title_files[array_rand($title_files)]; $titleLines = file($randomtitleFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $moban = preg_replace_callback('/\{标题\}|\{随机标题\}/', function () use ($titleLines, $zmtitleSwitch) { $randomTitle = trim($titleLines[array_rand($titleLines)]); if ($zmtitleSwitch == 1) { // 使用encodeValue转码 $randomTitle = encodeValue($randomTitle); } return $randomTitle; }, $moban); $reci_files = glob('data/reci/*.txt'); $randomreciFile = $reci_files[array_rand($reci_files)]; $reciLines = file($randomreciFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $moban = preg_replace_callback('/\{热词\}|\{随机热词\}/', function () use ($reciLines, $reciSwitch) { $randomHotWord = trim($reciLines[array_rand($reciLines)]); if ($reciSwitch == 1) { $randomHotWord = encodeValue($randomHotWord); } return $randomHotWord; }, $moban); // 栏目名称与栏目URL(用于 {随机栏目} / {随机栏目URL}) // 如果以后你在 data/mulu.txt 里维护栏目,可以改成从文件读取 $lanmuList = [ '系统工具', '聊天社交', '视频软件', '图形图像', '网络工具', '音乐软件', '办公软件', '安全防护', '游戏娱乐', '教育学习', '生活服务', '软件专题' ]; $randomLanmu = $lanmuList[array_rand($lanmuList)]; $lanmuUrl = 'http://' . $_SERVER['HTTP_HOST'] . '/soft/'; $moban = str_replace('{随机栏目}', $randomLanmu, $moban); $moban = str_replace('{随机栏目URL}', $lanmuUrl, $moban); // 随机评论标签:{随机评论1} ~ {随机评论20} // 需求:pinglun.txt 至少准备 100 条评论;每次页面刷新随机显示 20 条,并随机带入本页关键词 $commentFile = __DIR__ . '/data/pinglun.txt'; if (is_file($commentFile)) { $commentLines = file($commentFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $commentLines = array_values(array_filter(array_map('trim', $commentLines))); if (!empty($commentLines)) { $maxDisplay = 20; // 模板中最多展示 20 条 // 打乱顺序,先取不重复的 shuffle($commentLines); $selected = array_slice($commentLines, 0, min($maxDisplay, count($commentLines))); // 如果评论总数不足 20 条,用随机重复填满 20 条,避免标签留空 while (count($selected) < $maxDisplay) { $selected[] = $commentLines[array_rand($commentLines)]; } // 当前页面可用的关键词(优先 selectedKeyword,其次 keyword) $commentKeyword = ''; if (!empty($selectedKeyword)) { $commentKeyword = trim($selectedKeyword); } elseif (!empty($keyword)) { $commentKeyword = trim($keyword); } // 写回模板:{随机评论1} ~ {随机评论20} foreach ($selected as $idx => $text) { // 在评论里随机嵌入关键词:优先用“软件”替换为关键词,否则在末尾追加 if ($commentKeyword !== '') { $replaced = false; if (mb_strpos($text, '软件') !== false) { $text = preg_replace('/软件/u', $commentKeyword, $text, 1); $replaced = true; } if (!$replaced) { $text .= ',' . $commentKeyword; } } if ($zmjuziSwitch == 1) { $text = encodeValue($text); } $moban = str_replace('{随机评论' . ($idx + 1) . '}', $text, $moban); } // 清理多余占位符(如模板里没用到的更高序号),避免首刷看到标签字样 $moban = preg_replace('/\{随机评论\d+\}/', '', $moban); } else { // 没有任何评论内容时,直接清空占位符 $moban = preg_replace('/\{随机评论\d+\}/', '', $moban); } } else { // 文件不存在,同样清空占位符,避免输出 {随机评论1} 之类的字样 $moban = preg_replace('/\{随机评论\d+\}/', '', $moban); } $url = $_SERVER['HTTP_HOST']; preg_match('/[\w][\w-]*\.(?:com\.cn|net\.cn|org\.cn|gov\.cn|ren|top|com|xyz|shop|mobi|kim|biz|work|store|online|wiki|video|show|world|chat|fund|guru|email|fashion|yoga|host|website|bio|green|pet|promo|VOTO|wang|sohu|net|vip|ink|red|ltd|auto|law|tech|art|love|social|cool|cfd|cx|today|company|gold|run|life|fit|space|archi|black|Lotto|pink|ski|citic|xin|club|site|info|pro|group|link|Beer|fun|design|center|team|zone|city|live|plus|pub|co|luxe|baidu|cloud|press|asia|blue|organic|poker|vote|com|net|space|pro|cyou|org|info|biz|me|mobi|name|cc|tv|co|io|in|cn|us|eu|uk|la|ws|au|jp|kr|shop|xyz|me|fun|store|ltd|pro|xin|vip|site|online|club|work|top|icu|cn|edu|net|org|gov|cc|biz|tech|info)(\/|$)/isU', $url, $match); $zym = $match[0]; $moban = str_replace("{根域名}", $zym, $moban); $moban = str_replace("{主域名}", $_SERVER['HTTP_HOST'], $moban); // 新增:城市占位符,结合子域名自动生成城市名(默认“全国”) $moban = str_replace("{城市}", $cityName, $moban); $moban = str_replace("