baidu tuison

This commit is contained in:
make
2026-01-19 21:58:00 +08:00
parent 0323018c8c
commit 934ead3e11
10 changed files with 1075 additions and 466 deletions

View File

@@ -1,476 +1,332 @@
<?php
/**
* GPT 新模板 URL Family PoolA 方案)
* - prefixIndex × templateIndex 生成
* - 每套都有 idA001…
* - 每个页面1 pattern + 1 route
* - 每套都有稳定 idA001…
* - 文件被 require 时,直接返回 array
* - task / CLI / Web 全安全
*/
function buildUrlFamilyPool(): array
{
/** 页面定义(你给的) */
$pages = [
'play' => [
'sort' => 1,
'prefix' => [
'video', // 主
'play', // 主
'vodplay', // 历史
'watch', // 英文
'kan', // 拼音(看)
'player', // 英文
'bofang', // 英文
'm3u8', // 英文
'bf', // 英文
],
'type' => 'play'
// =====================
// 1⃣ 页面定义
// =====================
$pages = [
'play' => [
'sort' => 1,
'prefix' => [
'video','play','vodplay','watch','kan','player','bofang','m3u8','bf',
],
'detail_forge' => [
'sort' => 2,
'prefix' => [
'video', // 主
'detail', // 主
'info', // 主
'vod', // 行业通用
'movie', // 英文
'film', // 英文
'xiangqing',
'shipin',
'neirong',
'dianying',
],
'type' => 'detail_forge'
'type' => 'play',
],
'detail_forge' => [
'sort' => 2,
'prefix' => [
'video','detail','info','vod','movie','film',
'xiangqing','shipin','neirong','dianying',
],
'detail' => [
'sort' => 3,
'prefix' => [
'video', // 主
'detail', // 主
'info', // 主
'vod', // 行业通用
'movie', // 英文
'film', // 英文
'xiangqing',
'shipin',
'neirong',
'dianying',
],
'type' => 'detail'
'type' => 'detail_forge',
],
'detail' => [
'sort' => 3,
'prefix' => [
'video','detail','info','vod','movie','film',
'xiangqing','shipin','neirong','dianying',
],
'category_child' => [
'sort' => 4,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_child'
'type' => 'detail',
],
'category_child' => [
'sort' => 4,
'prefix' => [
'fenlei','category','class','type','genres','leixing','videotype',
],
'category_parent' => [
'sort' => 5,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_parent'
'type' => 'category_child',
],
'category_parent' => [
'sort' => 5,
'prefix' => [
'fenlei','category','class','type','genres','leixing','videotype',
],
'rank_list' => [
'sort' => 6,
'prefix' => [
'top', // 主
'rank', // 主
'paihangban', // 拼音
'ranking', // 英文
'hot', // 热门(谨慎)
'phb',
],
'type' => 'rank_list'
'type' => 'category_parent',
],
'rank_list' => [
'sort' => 6,
'prefix' => [
'top','rank','paihangban','ranking','hot','phb',
],
'category_home' => [
'sort' => 7,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_home'
'type' => 'rank_list',
],
'category_home' => [
'sort' => 7,
'prefix' => [
'fenlei','category','class','type','genres','leixing','videotype',
],
'rank_index' => [
'sort' => 8,
'prefix' => [
'top', // 主
'rank', // 主
'paihangban', // 拼音
'ranking', // 英文
'hot', // 热门(谨慎)
'phb',
],
'type' => 'rank_index'
'type' => 'category_home',
],
'rank_index' => [
'sort' => 8,
'prefix' => [
'top','rank','paihangban','ranking','hot','phb',
],
'search' => [
'sort' => 9,
'prefix' => [
'search', // 主
'query', // 主
'sou', // 拼音
'find', // 英文
'get'
],
'type' => 'search'
'type' => 'rank_index',
],
'search' => [
'sort' => 9,
'prefix' => [
'search','query','sou','find','get',
],
'history' => [
'sort' => 10,
'prefix' => [
'history', // 主
'his', // 简写
'jilu', // 拼音
'record', // 英文
],
'type' => 'history'
'type' => 'search',
],
'history' => [
'sort' => 10,
'prefix' => [
'history','his','jilu','record',
],
];
'type' => 'history',
],
];
/** 每个 type 的 8 套模板(你已测试可用) */
$templates = [
'category_home' => [
'pattern' => [
'{prefix}',
'{prefix}/index',
'{prefix}/home',
'{prefix}/p',
'{prefix}/1',
'{prefix}-1',
'{prefix}-index',
'{prefix}-home',
],
'routes' => [
'/{prefix}',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/p',
'/{prefix}/1',
'/{prefix}/-1',
'/{prefix}-index',
'/{prefix}-home',
],
// =====================
// 2⃣ 模板定义(每类 8 套)
// =====================
$templates = [
'category_home' => [
'pattern' => [
'{prefix}','{prefix}/index','{prefix}/home','{prefix}/p',
'{prefix}/1','{prefix}-1','{prefix}-index','{prefix}-home',
],
'category_parent' => [
'pattern' => [
'{prefix}/{strParentCategory}',
'{prefix}/{strParentCategory}/index',
'{prefix}/{strParentCategory}/home',
'{prefix}/p/{strParentCategory}',
'{prefix}/1/{strParentCategory}',
'{prefix}/1-{strParentCategory}',
'{prefix}/{strParentCategory}/1',
'{prefix}/{strParentCategory}-1',
],
'routes' => [
'/{prefix}/:strParentCategory',
'/{prefix}/:strParentCategory/index',
'/{prefix}/:strParentCategory/home',
'/{prefix}/p/:strParentCategory',
'/{prefix}/1/:strParentCategory',
'/{prefix}/1-:strParentCategory',
'/{prefix}/:strParentCategory/1',
'/{prefix}/:strParentCategory-1',
],
'routes' => [
'/{prefix}','/{prefix}/index','/{prefix}/home','/{prefix}/p',
'/{prefix}/1','/{prefix}-1','/{prefix}-index','/{prefix}-home',
],
],
'category_child' => [
'pattern' => [
'{prefix}/{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}/{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-{intPage}',
],
'routes' => [
'/{prefix}/:strParentCategory/:strCategory/page:intPage',
'/{prefix}/:strParentCategory/:strCategory-page:intPage',
'/{prefix}-:strParentCategory/:strCategory/page:intPage',
'/{prefix}-:strParentCategory/:strCategory-page:intPage',
'/{prefix}/:strParentCategory/:strCategory/:intPage',
'/{prefix}/:strParentCategory/:strCategory-:intPage',
'/{prefix}-:strParentCategory/:strCategory/:intPage',
'/{prefix}-:strParentCategory/:strCategory-:intPage',
],
'category_parent' => [
'pattern' => [
'{prefix}/{strParentCategory}','{prefix}/{strParentCategory}/index',
'{prefix}/{strParentCategory}/home','{prefix}/p/{strParentCategory}',
'{prefix}/1/{strParentCategory}','{prefix}/1-{strParentCategory}',
'{prefix}/{strParentCategory}/1','{prefix}/{strParentCategory}-1',
],
'rank_index' => [
'pattern' => [
'{prefix}',
'{prefix}/index',
'{prefix}/all',
'{prefix}/home',
'{prefix}/1',
'{prefix}-index',
'{prefix}-all',
'{prefix}-home',
],
'routes' => [
'/{prefix}',
'/{prefix}/index',
'/{prefix}/all',
'/{prefix}/home',
'/{prefix}/1',
'/{prefix}-index',
'/{prefix}-all',
'/{prefix}-home',
],
'routes' => [
'/{prefix}/:strParentCategory','/{prefix}/:strParentCategory/index',
'/{prefix}/:strParentCategory/home','/{prefix}/p/:strParentCategory',
'/{prefix}/1/:strParentCategory','/{prefix}/1-:strParentCategory',
'/{prefix}/:strParentCategory/1','/{prefix}/:strParentCategory-1',
],
],
'rank_list' => [
'pattern' => [
'{prefix}/{strSortType}',
'{prefix}/{strSortType}/index',
'{prefix}/{strSortType}/home',
'{prefix}/{strSortType}/1',
'{prefix}/{strSortType}-1',
'{prefix}-{strSortType}',
'{prefix}-{strSortType}/index',
'{prefix}-{strSortType}/1',
],
'routes' => [
'/{prefix}/:strSortType',
'/{prefix}/:strSortType/index',
'/{prefix}/:strSortType/home',
'/{prefix}/:strSortType/1',
'/{prefix}/:strSortType-1',
'/{prefix}-:strSortType',
'/{prefix}-:strSortType/index',
'/{prefix}-:strSortType/1',
],
'category_child' => [
'pattern' => [
'{prefix}/{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}/{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-{intPage}',
],
'detail' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}',
'{prefix}/{intVId}-{strPinyin}',
'{prefix}/{strPinyin}/{intVId}',
'{prefix}/{intVId}',
'{prefix}-{strPinyin}-{intVId}',
'{prefix}-{intVId}-{strPinyin}',
'{prefix}/id-{intVId}',
'{prefix}/pinyin-{strPinyin}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId',
'/{prefix}/:intVId-:strPinyin',
'/{prefix}/:strPinyin/:intVId',
'/{prefix}/:intVId',
'/{prefix}-:strPinyin-:intVId',
'/{prefix}-:intVId-:strPinyin',
'/{prefix}/id-:intVId',
'/{prefix}/pinyin-:strPinyin',
],
'routes' => [
'/{prefix}/:strParentCategory/:strCategory/page:intPage',
'/{prefix}/:strParentCategory/:strCategory-page:intPage',
'/{prefix}-:strParentCategory/:strCategory/page:intPage',
'/{prefix}-:strParentCategory/:strCategory-page:intPage',
'/{prefix}/:strParentCategory/:strCategory/:intPage',
'/{prefix}/:strParentCategory/:strCategory-:intPage',
'/{prefix}-:strParentCategory/:strCategory/:intPage',
'/{prefix}-:strParentCategory/:strCategory-:intPage',
],
],
'detail_forge' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{intVForgeId}',
'{prefix}/{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/{strPinyin}/{intVId}-{intVForgeId}',
'{prefix}/{intVId}/{intVForgeId}',
'{prefix}-{strPinyin}-{intVId}/{intVForgeId}',
'{prefix}-{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/id-{intVId}-{intVForgeId}',
'{prefix}/pinyin-{strPinyin}/{intVForgeId}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:intVForgeId',
'/{prefix}/:intVId-:strPinyin/:intVForgeId',
'/{prefix}/:strPinyin/:intVId-:intVForgeId',
'/{prefix}/:intVId/:intVForgeId',
'/{prefix}-:strPinyin-:intVId/:intVForgeId',
'/{prefix}-:intVId-:strPinyin/:intVForgeId',
'/{prefix}/id-:intVId-:intVForgeId',
'/{prefix}/pinyin-:strPinyin/:intVForgeId',
],
'rank_index' => [
'pattern' => [
'{prefix}','{prefix}/index','{prefix}/all','{prefix}/home',
'{prefix}/1','{prefix}-index','{prefix}-all','{prefix}-home',
],
'play' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{strPinyin}-{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}-{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPinyin}/{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}/{strPlayType}-{intPlayIndex}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:strPinyin-:intVId/:strPlayType-:intPlayIndex',
'/{prefix}/:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:intVId/:strPlayType-:intPlayIndex',
'/{prefix}-:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPinyin/:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId/:strPlayType-:intPlayIndex',
],
'routes' => [
'/{prefix}','/{prefix}/index','/{prefix}/all','/{prefix}/home',
'/{prefix}/1','/{prefix}-index','/{prefix}-all','/{prefix}-home',
],
],
'search' => [
'pattern' => [
'{prefix}',
'{prefix}.html',
'{prefix}/index',
'{prefix}/home',
'{prefix}/keywords',
'{prefix}-index',
'{prefix}-home',
'{prefix}-keywords',
],
'routes' => [
'/{prefix}',
'/{prefix}.html',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/keywords',
'/{prefix}-index',
'/{prefix}-home',
'/{prefix}-keywords',
],
'rank_list' => [
'pattern' => [
'{prefix}/{strSortType}','{prefix}/{strSortType}/index',
'{prefix}/{strSortType}/home','{prefix}/{strSortType}/1',
'{prefix}/{strSortType}-1','{prefix}-{strSortType}',
'{prefix}-{strSortType}/index','{prefix}-{strSortType}/1',
],
'history' => [
'pattern' => [
'{prefix}',
'{prefix}.html',
'{prefix}/index',
'{prefix}/home',
'{prefix}/keywords',
'{prefix}-index',
'{prefix}-home',
'{prefix}-keywords',
],
'routes' => [
'/{prefix}',
'/{prefix}.html',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/keywords',
'/{prefix}-index',
'/{prefix}-home',
'/{prefix}-keywords',
],
'routes' => [
'/{prefix}/:strSortType','/{prefix}/:strSortType/index',
'/{prefix}/:strSortType/home','/{prefix}/:strSortType/1',
'/{prefix}/:strSortType-1','/{prefix}-:strSortType',
'/{prefix}-:strSortType/index','/{prefix}-:strSortType/1',
],
];
],
'detail' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}','{prefix}/{intVId}-{strPinyin}',
'{prefix}/{strPinyin}/{intVId}','{prefix}/{intVId}',
'{prefix}-{strPinyin}-{intVId}','{prefix}-{intVId}-{strPinyin}',
'{prefix}/id-{intVId}','{prefix}/pinyin-{strPinyin}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId','/{prefix}/:intVId-:strPinyin',
'/{prefix}/:strPinyin/:intVId','/{prefix}/:intVId',
'/{prefix}-:strPinyin-:intVId','/{prefix}-:intVId-:strPinyin',
'/{prefix}/id-:intVId','/{prefix}/pinyin-:strPinyin',
],
],
// 🔴【新增 1】加载 index落盘 ID
$indexFile = __DIR__ . '/url_family_index.php';
$index = file_exists($indexFile) ? require $indexFile : [];
'detail_forge' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{intVForgeId}',
'{prefix}/{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/{strPinyin}/{intVId}-{intVForgeId}',
'{prefix}/{intVId}/{intVForgeId}',
'{prefix}-{strPinyin}-{intVId}/{intVForgeId}',
'{prefix}-{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/id-{intVId}-{intVForgeId}',
'{prefix}/pinyin-{strPinyin}/{intVForgeId}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:intVForgeId',
'/{prefix}/:intVId-:strPinyin/:intVForgeId',
'/{prefix}/:strPinyin/:intVId-:intVForgeId',
'/{prefix}/:intVId/:intVForgeId',
'/{prefix}-:strPinyin-:intVId/:intVForgeId',
'/{prefix}-:intVId-:strPinyin/:intVForgeId',
'/{prefix}/id-:intVId-:intVForgeId',
'/{prefix}/pinyin-:strPinyin/:intVForgeId',
],
],
// 🔴【新增 2】计算当前最大 A 编号
$maxId = 0;
foreach ($index as $aid) {
$num = (int)substr($aid, 1);
if ($num > $maxId) {
$maxId = $num;
}
'play' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{strPinyin}-{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}-{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPinyin}/{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}/{strPlayType}-{intPlayIndex}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:strPinyin-:intVId/:strPlayType-:intPlayIndex',
'/{prefix}/:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:intVId/:strPlayType-:intPlayIndex',
'/{prefix}-:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPinyin/:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId/:strPlayType-:intPlayIndex',
],
],
'search' => [
'pattern' => [
'{prefix}','{prefix}.html','{prefix}/index','{prefix}/home',
'{prefix}/keywords','{prefix}-index','{prefix}-home','{prefix}-keywords',
],
'routes' => [
'/{prefix}','/{prefix}.html','/{prefix}/index','/{prefix}/home',
'/{prefix}/keywords','/{prefix}-index','/{prefix}-home','/{prefix}-keywords',
],
],
'history' => [
'pattern' => [
'{prefix}','{prefix}.html','{prefix}/index','{prefix}/home',
'{prefix}/keywords','{prefix}-index','{prefix}-home','{prefix}-keywords',
],
'routes' => [
'/{prefix}','/{prefix}.html','/{prefix}/index','/{prefix}/home',
'/{prefix}/keywords','/{prefix}-index','/{prefix}-home','/{prefix}-keywords',
],
],
];
// =====================
// 3⃣ ID 索引(落盘)
// =====================
$indexFile = __DIR__ . '/url_family_index.php';
$index = file_exists($indexFile) ? require $indexFile : [];
// =====================
// 4⃣ 计算当前最大 A 编号
// =====================
$maxId = 0;
foreach ($index as $aid) {
$num = (int)substr($aid, 1);
if ($num > $maxId) {
$maxId = $num;
}
// 页面按 sort 排序(保证路由注册顺序)
uasort($pages, fn($a, $b) => $a['sort'] <=> $b['sort']);
// prefix 套数
$prefixSuiteCount = max(array_map(fn($p) => count($p['prefix']), $pages));
$families = [];
// ❌【删除】$seq = 1;
for ($pi = 0; $pi < $prefixSuiteCount; $pi++) {
for ($ti = 0; $ti < 8; $ti++) {
/**
* 🔴【新增 3】构造 family 唯一指纹 key
* 只要 page / prefix / 模板索引一样URL 身份就一样
*/
$familyKeyParts = [];
foreach ($pages as $pageKey => $page) {
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$familyKeyParts[] = $pageKey . ':' . $prefix;
}
$familyKey = implode('|', $familyKeyParts) . '|tpl' . $ti;
// 🔴【新增 4】从 index 取 A 编号(没有就新增)
if (!isset($index[$familyKey])) {
$maxId++;
$index[$familyKey] = 'A' . str_pad((string)$maxId, 3, '0', STR_PAD_LEFT);
}
$aid = $index[$familyKey];
// 🔴【修改】family 的 id 不再用 $seq
$family = [
'id' => $aid,
'home' => [
'pattern' => '',
'routes' => [
'/'
]
],
];
foreach ($pages as $pageKey => $page) {
$type = $page['type'];
if (!isset($templates[$type])) {
continue;
}
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$pattern = str_replace('{prefix}', $prefix, $templates[$type]['pattern'][$ti]);
$route = str_replace('{prefix}', $prefix, $templates[$type]['routes'][$ti]);
$family[$pageKey] = [
'sort' => $page['sort'],
'pattern' => $pattern,
'routes' => [$route],
];
}
// 🔴【修改】用 A 编号做 key避免被重排
$families[$aid] = $family;
}
}
// 🔴【新增 5】index 落盘(只会 append
file_put_contents(
$indexFile,
"<?php\nreturn " . var_export($index, true) . ";\n"
);
// 🔴【新增 6】按 A 编号排序,输出稳定顺序
ksort($families);
return array_values($families);
}
return buildUrlFamilyPool();
// =====================
// 5⃣ 构造 families
// =====================
uasort($pages, fn($a, $b) => $a['sort'] <=> $b['sort']);
$prefixSuiteCount = max(array_map(fn($p) => count($p['prefix']), $pages));
$families = [];
for ($pi = 0; $pi < $prefixSuiteCount; $pi++) {
for ($ti = 0; $ti < 8; $ti++) {
$familyKeyParts = [];
foreach ($pages as $pageKey => $page) {
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$familyKeyParts[] = $pageKey . ':' . $prefix;
}
$familyKey = implode('|', $familyKeyParts) . '|tpl' . $ti;
if (!isset($index[$familyKey])) {
$maxId++;
$index[$familyKey] = 'A' . str_pad((string)$maxId, 3, '0', STR_PAD_LEFT);
}
$aid = $index[$familyKey];
$family = [
'id' => $aid,
'home' => [
'pattern' => '',
'routes' => ['/'],
],
];
foreach ($pages as $pageKey => $page) {
$type = $page['type'];
if (!isset($templates[$type])) {
continue;
}
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$pattern = str_replace('{prefix}', $prefix, $templates[$type]['pattern'][$ti]);
$route = str_replace('{prefix}', $prefix, $templates[$type]['routes'][$ti]);
$family[$pageKey] = [
'sort' => $page['sort'],
'pattern' => $pattern,
'routes' => [$route],
];
}
$families[$aid] = $family;
}
}
// =====================
// 6⃣ index 落盘 + 排序返回
// =====================
file_put_contents(
$indexFile,
"<?php\nreturn " . var_export($index, true) . ";\n"
);
ksort($families);
return array_values($families);

View File

@@ -0,0 +1,476 @@
<?php
/**
* GPT 新模板 URL Family PoolA 方案)
* - prefixIndex × templateIndex 生成
* - 每套都有 idA001…
* - 每个页面1 pattern + 1 route
*/
function buildUrlFamilyPool(): array
{
/** 页面定义(你给的) */
$pages = [
'play' => [
'sort' => 1,
'prefix' => [
'video', // 主
'play', // 主
'vodplay', // 历史
'watch', // 英文
'kan', // 拼音(看)
'player', // 英文
'bofang', // 英文
'm3u8', // 英文
'bf', // 英文
],
'type' => 'play'
],
'detail_forge' => [
'sort' => 2,
'prefix' => [
'video', // 主
'detail', // 主
'info', // 主
'vod', // 行业通用
'movie', // 英文
'film', // 英文
'xiangqing',
'shipin',
'neirong',
'dianying',
],
'type' => 'detail_forge'
],
'detail' => [
'sort' => 3,
'prefix' => [
'video', // 主
'detail', // 主
'info', // 主
'vod', // 行业通用
'movie', // 英文
'film', // 英文
'xiangqing',
'shipin',
'neirong',
'dianying',
],
'type' => 'detail'
],
'category_child' => [
'sort' => 4,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_child'
],
'category_parent' => [
'sort' => 5,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_parent'
],
'rank_list' => [
'sort' => 6,
'prefix' => [
'top', // 主
'rank', // 主
'paihangban', // 拼音
'ranking', // 英文
'hot', // 热门(谨慎)
'phb',
],
'type' => 'rank_list'
],
'category_home' => [
'sort' => 7,
'prefix' => [
'fenlei', // 主
'category', // 英文
'class', // 主
'type', // 主
'genres', // 英文(类型)
'leixing', // 拼音
'videotype', // 拼音
],
'type' => 'category_home'
],
'rank_index' => [
'sort' => 8,
'prefix' => [
'top', // 主
'rank', // 主
'paihangban', // 拼音
'ranking', // 英文
'hot', // 热门(谨慎)
'phb',
],
'type' => 'rank_index'
],
'search' => [
'sort' => 9,
'prefix' => [
'search', // 主
'query', // 主
'sou', // 拼音
'find', // 英文
'get'
],
'type' => 'search'
],
'history' => [
'sort' => 10,
'prefix' => [
'history', // 主
'his', // 简写
'jilu', // 拼音
'record', // 英文
],
'type' => 'history'
],
];
/** 每个 type 的 8 套模板(你已测试可用) */
$templates = [
'category_home' => [
'pattern' => [
'{prefix}',
'{prefix}/index',
'{prefix}/home',
'{prefix}/p',
'{prefix}/1',
'{prefix}-1',
'{prefix}-index',
'{prefix}-home',
],
'routes' => [
'/{prefix}',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/p',
'/{prefix}/1',
'/{prefix}/-1',
'/{prefix}-index',
'/{prefix}-home',
],
],
'category_parent' => [
'pattern' => [
'{prefix}/{strParentCategory}',
'{prefix}/{strParentCategory}/index',
'{prefix}/{strParentCategory}/home',
'{prefix}/p/{strParentCategory}',
'{prefix}/1/{strParentCategory}',
'{prefix}/1-{strParentCategory}',
'{prefix}/{strParentCategory}/1',
'{prefix}/{strParentCategory}-1',
],
'routes' => [
'/{prefix}/:strParentCategory',
'/{prefix}/:strParentCategory/index',
'/{prefix}/:strParentCategory/home',
'/{prefix}/p/:strParentCategory',
'/{prefix}/1/:strParentCategory',
'/{prefix}/1-:strParentCategory',
'/{prefix}/:strParentCategory/1',
'/{prefix}/:strParentCategory-1',
],
],
'category_child' => [
'pattern' => [
'{prefix}/{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/page{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-page{intPage}',
'{prefix}/{strParentCategory}/{strCategory}/{intPage}',
'{prefix}/{strParentCategory}/{strCategory}-{intPage}',
'{prefix}-{strParentCategory}/{strCategory}/{intPage}',
'{prefix}-{strParentCategory}/{strCategory}-{intPage}',
],
'routes' => [
'/{prefix}/:strParentCategory/:strCategory/page:intPage',
'/{prefix}/:strParentCategory/:strCategory-page:intPage',
'/{prefix}-:strParentCategory/:strCategory/page:intPage',
'/{prefix}-:strParentCategory/:strCategory-page:intPage',
'/{prefix}/:strParentCategory/:strCategory/:intPage',
'/{prefix}/:strParentCategory/:strCategory-:intPage',
'/{prefix}-:strParentCategory/:strCategory/:intPage',
'/{prefix}-:strParentCategory/:strCategory-:intPage',
],
],
'rank_index' => [
'pattern' => [
'{prefix}',
'{prefix}/index',
'{prefix}/all',
'{prefix}/home',
'{prefix}/1',
'{prefix}-index',
'{prefix}-all',
'{prefix}-home',
],
'routes' => [
'/{prefix}',
'/{prefix}/index',
'/{prefix}/all',
'/{prefix}/home',
'/{prefix}/1',
'/{prefix}-index',
'/{prefix}-all',
'/{prefix}-home',
],
],
'rank_list' => [
'pattern' => [
'{prefix}/{strSortType}',
'{prefix}/{strSortType}/index',
'{prefix}/{strSortType}/home',
'{prefix}/{strSortType}/1',
'{prefix}/{strSortType}-1',
'{prefix}-{strSortType}',
'{prefix}-{strSortType}/index',
'{prefix}-{strSortType}/1',
],
'routes' => [
'/{prefix}/:strSortType',
'/{prefix}/:strSortType/index',
'/{prefix}/:strSortType/home',
'/{prefix}/:strSortType/1',
'/{prefix}/:strSortType-1',
'/{prefix}-:strSortType',
'/{prefix}-:strSortType/index',
'/{prefix}-:strSortType/1',
],
],
'detail' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}',
'{prefix}/{intVId}-{strPinyin}',
'{prefix}/{strPinyin}/{intVId}',
'{prefix}/{intVId}',
'{prefix}-{strPinyin}-{intVId}',
'{prefix}-{intVId}-{strPinyin}',
'{prefix}/id-{intVId}',
'{prefix}/pinyin-{strPinyin}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId',
'/{prefix}/:intVId-:strPinyin',
'/{prefix}/:strPinyin/:intVId',
'/{prefix}/:intVId',
'/{prefix}-:strPinyin-:intVId',
'/{prefix}-:intVId-:strPinyin',
'/{prefix}/id-:intVId',
'/{prefix}/pinyin-:strPinyin',
],
],
'detail_forge' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{intVForgeId}',
'{prefix}/{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/{strPinyin}/{intVId}-{intVForgeId}',
'{prefix}/{intVId}/{intVForgeId}',
'{prefix}-{strPinyin}-{intVId}/{intVForgeId}',
'{prefix}-{intVId}-{strPinyin}/{intVForgeId}',
'{prefix}/id-{intVId}-{intVForgeId}',
'{prefix}/pinyin-{strPinyin}/{intVForgeId}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:intVForgeId',
'/{prefix}/:intVId-:strPinyin/:intVForgeId',
'/{prefix}/:strPinyin/:intVId-:intVForgeId',
'/{prefix}/:intVId/:intVForgeId',
'/{prefix}-:strPinyin-:intVId/:intVForgeId',
'/{prefix}-:intVId-:strPinyin/:intVForgeId',
'/{prefix}/id-:intVId-:intVForgeId',
'/{prefix}/pinyin-:strPinyin/:intVForgeId',
],
],
'play' => [
'pattern' => [
'{prefix}/{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{strPinyin}-{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}/{intVId}/{strPlayType}-{intPlayIndex}',
'{prefix}-{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPinyin}/{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}-{strPlayType}-{intPlayIndex}',
'{prefix}-{intVId}/{strPlayType}-{intPlayIndex}',
],
'routes' => [
'/{prefix}/:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:strPinyin-:intVId/:strPlayType-:intPlayIndex',
'/{prefix}/:intVId-:strPlayType-:intPlayIndex',
'/{prefix}/:intVId/:strPlayType-:intPlayIndex',
'/{prefix}-:strPinyin-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPinyin/:strPlayType-:intPlayIndex',
'/{prefix}-:intVId-:strPlayType-:intPlayIndex',
'/{prefix}-:intVId/:strPlayType-:intPlayIndex',
],
],
'search' => [
'pattern' => [
'{prefix}',
'{prefix}.html',
'{prefix}/index',
'{prefix}/home',
'{prefix}/keywords',
'{prefix}-index',
'{prefix}-home',
'{prefix}-keywords',
],
'routes' => [
'/{prefix}',
'/{prefix}.html',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/keywords',
'/{prefix}-index',
'/{prefix}-home',
'/{prefix}-keywords',
],
],
'history' => [
'pattern' => [
'{prefix}',
'{prefix}.html',
'{prefix}/index',
'{prefix}/home',
'{prefix}/keywords',
'{prefix}-index',
'{prefix}-home',
'{prefix}-keywords',
],
'routes' => [
'/{prefix}',
'/{prefix}.html',
'/{prefix}/index',
'/{prefix}/home',
'/{prefix}/keywords',
'/{prefix}-index',
'/{prefix}-home',
'/{prefix}-keywords',
],
],
];
// 🔴【新增 1】加载 index落盘 ID
$indexFile = __DIR__ . '/url_family_index.php';
$index = file_exists($indexFile) ? require $indexFile : [];
// 🔴【新增 2】计算当前最大 A 编号
$maxId = 0;
foreach ($index as $aid) {
$num = (int)substr($aid, 1);
if ($num > $maxId) {
$maxId = $num;
}
}
// 页面按 sort 排序(保证路由注册顺序)
uasort($pages, fn($a, $b) => $a['sort'] <=> $b['sort']);
// prefix 套数
$prefixSuiteCount = max(array_map(fn($p) => count($p['prefix']), $pages));
$families = [];
// ❌【删除】$seq = 1;
for ($pi = 0; $pi < $prefixSuiteCount; $pi++) {
for ($ti = 0; $ti < 8; $ti++) {
/**
* 🔴【新增 3】构造 family 唯一指纹 key
* 只要 page / prefix / 模板索引一样URL 身份就一样
*/
$familyKeyParts = [];
foreach ($pages as $pageKey => $page) {
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$familyKeyParts[] = $pageKey . ':' . $prefix;
}
$familyKey = implode('|', $familyKeyParts) . '|tpl' . $ti;
// 🔴【新增 4】从 index 取 A 编号(没有就新增)
if (!isset($index[$familyKey])) {
$maxId++;
$index[$familyKey] = 'A' . str_pad((string)$maxId, 3, '0', STR_PAD_LEFT);
}
$aid = $index[$familyKey];
// 🔴【修改】family 的 id 不再用 $seq
$family = [
'id' => $aid,
'home' => [
'pattern' => '',
'routes' => [
'/'
]
],
];
foreach ($pages as $pageKey => $page) {
$type = $page['type'];
if (!isset($templates[$type])) {
continue;
}
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
$pattern = str_replace('{prefix}', $prefix, $templates[$type]['pattern'][$ti]);
$route = str_replace('{prefix}', $prefix, $templates[$type]['routes'][$ti]);
$family[$pageKey] = [
'sort' => $page['sort'],
'pattern' => $pattern,
'routes' => [$route],
];
}
// 🔴【修改】用 A 编号做 key避免被重排
$families[$aid] = $family;
}
}
// 🔴【新增 5】index 落盘(只会 append
file_put_contents(
$indexFile,
"<?php\nreturn " . var_export($index, true) . ";\n"
);
// 🔴【新增 6】按 A 编号排序,输出稳定顺序
ksort($families);
return array_values($families);
}
return buildUrlFamilyPool();