2026-06-14 14:00:24 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 加载站点 check_config 配置(define 常量)
|
|
|
|
|
|
*/
|
|
|
|
|
|
class ConfigLoader
|
|
|
|
|
|
{
|
|
|
|
|
|
public static function loadFile($configFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (file_exists($configFile)) {
|
|
|
|
|
|
include $configFile;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return string 实际加载的配置名
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function loadByName($configName, $baseDir = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$baseDir = $baseDir ?: dirname(__DIR__);
|
|
|
|
|
|
$configName = self::sanitizeConfigName($configName);
|
|
|
|
|
|
$configFile = $baseDir . '/check_config/' . $configName . '_config.php';
|
|
|
|
|
|
if (file_exists($configFile)) {
|
|
|
|
|
|
self::loadFile($configFile);
|
|
|
|
|
|
return $configName;
|
|
|
|
|
|
}
|
|
|
|
|
|
self::loadFile($baseDir . '/check_config/index_config.php');
|
|
|
|
|
|
return 'index';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return string 实际加载的配置名
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function loadByHost($host, $baseDir = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$baseDir = $baseDir ?: dirname(__DIR__);
|
|
|
|
|
|
if (!class_exists('DomainRepository', false)) {
|
|
|
|
|
|
require_once dirname(__DIR__) . '/lib/Cloak/DomainRepository.php';
|
|
|
|
|
|
}
|
|
|
|
|
|
$name = DomainRepository::resolveConfigNameForHost((string) $host, $baseDir);
|
|
|
|
|
|
return self::loadByName($name, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-06-22 21:55:33 +08:00
|
|
|
|
* 同域多落地页:入口脚本有独立配置时优先脚本名;
|
|
|
|
|
|
* 伪静态/rewrite 落到 index.php 时从 REQUEST_URI 路径解析配置名;
|
|
|
|
|
|
* 否则按 HTTP Host(多站/宝塔);再回退脚本名或 index
|
2026-06-14 14:00:24 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @return string 实际加载的配置名
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function loadForRequest($scriptBaseName, $host = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$host = $host ?? ($_SERVER['HTTP_HOST'] ?? '');
|
2026-06-15 22:42:59 +08:00
|
|
|
|
$baseDir = dirname(__DIR__);
|
|
|
|
|
|
$scriptSanitized = self::sanitizeConfigName((string) $scriptBaseName);
|
2026-06-22 21:55:33 +08:00
|
|
|
|
if (self::hasConfigFile($scriptSanitized, $baseDir)) {
|
2026-06-15 22:42:59 +08:00
|
|
|
|
return self::loadByName($scriptSanitized);
|
|
|
|
|
|
}
|
2026-06-22 21:55:33 +08:00
|
|
|
|
|
|
|
|
|
|
$uriConfigName = self::resolveConfigNameFromRequestUri($baseDir);
|
|
|
|
|
|
if ($uriConfigName !== null) {
|
|
|
|
|
|
return self::loadByName($uriConfigName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-14 14:00:24 +08:00
|
|
|
|
if ($host !== '') {
|
|
|
|
|
|
return self::loadByHost($host);
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($scriptBaseName !== null && $scriptBaseName !== '') {
|
|
|
|
|
|
return self::loadByName($scriptBaseName);
|
|
|
|
|
|
}
|
|
|
|
|
|
return self::loadByName('index');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-22 21:55:33 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 从 URL 或路径解析落地页配置名(不含 query)。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return string|null
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function resolveConfigNameFromUrl($url, $baseDir = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($url === '') {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
$path = parse_url($url, PHP_URL_PATH);
|
|
|
|
|
|
if (!is_string($path)) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return self::resolveConfigNameFromPath($path, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 从 REQUEST_URI 路径段解析落地页配置名(不含 query)。
|
|
|
|
|
|
* 用于 nginx try_files → index.php 等场景:/PH-fwa037?utm=... 仍应对应 PH-fwa037 配置。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return string|null 可加载的配置名;无法解析时 null
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function resolveConfigNameFromRequestUri($baseDir = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$uri = (string) ($_SERVER['REQUEST_URI'] ?? '');
|
|
|
|
|
|
if ($uri === '') {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
$path = parse_url($uri, PHP_URL_PATH);
|
|
|
|
|
|
if (!is_string($path)) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return self::resolveConfigNameFromPath($path, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return string|null
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function resolveConfigNameFromPath($path, $baseDir = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$baseDir = $baseDir ?: dirname(__DIR__);
|
|
|
|
|
|
$path = (string) $path;
|
|
|
|
|
|
if ($path === '' || $path === '/') {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$basename = basename($path);
|
|
|
|
|
|
$name = self::sanitizeConfigName($basename);
|
|
|
|
|
|
if ($name === 'index' || $name === 'ip_check' || $name === 'f_check') {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!self::hasConfigFile($name, $baseDir)) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return $name;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 二次风控 f_check / byApiRisk:优先 hdata.config_name,其次落地页 URL 路径,再 Host 映射。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $pageUrl hdata.domain(浏览器当前页完整 URL)
|
|
|
|
|
|
* @param string|null $fallbackHost 兜底 Host(通常为 HTTP_HOST)
|
|
|
|
|
|
* @param string|null $explicitConfigName hdata.config_name(ip_check 阶段已解析的配置名)
|
|
|
|
|
|
* @return string 实际加载的配置名
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function loadForFingerprint($pageUrl, $fallbackHost = null, $explicitConfigName = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
$baseDir = dirname(__DIR__);
|
|
|
|
|
|
|
|
|
|
|
|
if ($explicitConfigName !== null && trim((string) $explicitConfigName) !== '') {
|
|
|
|
|
|
$explicit = self::sanitizeConfigName($explicitConfigName);
|
|
|
|
|
|
if (self::hasConfigFile($explicit, $baseDir)) {
|
|
|
|
|
|
return self::loadByName($explicit, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$fromUrl = self::resolveConfigNameFromUrl((string) $pageUrl, $baseDir);
|
|
|
|
|
|
if ($fromUrl !== null) {
|
|
|
|
|
|
return self::loadByName($fromUrl, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$host = $fallbackHost ?? ($_SERVER['HTTP_HOST'] ?? '');
|
|
|
|
|
|
if ($host !== '') {
|
|
|
|
|
|
return self::loadByHost($host, $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return self::loadByName('index', $baseDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @param string $configName
|
|
|
|
|
|
*/
|
|
|
|
|
|
private static function hasConfigFile($configName, $baseDir)
|
|
|
|
|
|
{
|
|
|
|
|
|
$configName = self::sanitizeConfigName($configName);
|
|
|
|
|
|
if ($configName === 'index' || $configName === 'ip_check') {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return file_exists($baseDir . '/check_config/' . $configName . '_config.php');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-14 14:00:24 +08:00
|
|
|
|
public static function sanitizeConfigName($name)
|
|
|
|
|
|
{
|
|
|
|
|
|
$name = trim((string) $name);
|
|
|
|
|
|
$name = str_replace('.php', '', $name);
|
|
|
|
|
|
if ($name === '' || !preg_match('/^[a-zA-Z0-9_-]+$/', $name)) {
|
|
|
|
|
|
return 'index';
|
|
|
|
|
|
}
|
|
|
|
|
|
return $name;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|