/** * Инициализация и выполнение редиректов * @param array $redirects Массив редиректов ['from' => 'to'] */ public static function init(array $redirects = []): void { self::$redirects = $redirects; $redirectData = self::findRedirect(); if ($redirectData && !self::isSameUrl(self::getCurrentUrl(), $redirectData['target'])) { LocalRedirect($redirectData['target'], true, '301 Moved Permanently'); } } /** * Получение текущего URL с параметрами */ private static function getCurrentUrl(): string { $server = Context::getCurrent()->getServer(); $protocol = $server->get('HTTPS') === 'on' ? 'https' : 'http'; return $protocol . '://' . $server->get('HTTP_HOST') . $server->get('REQUEST_URI'); } /** * Получение базового URL сайта */ private static function getSiteUrl(): string { $server = Context::getCurrent()->getServer(); $protocol = $server->get('HTTPS') === 'on' ? 'https' : 'http'; $host = defined('SITE_SERVER_NAME') && SITE_SERVER_NAME ? SITE_SERVER_NAME : $server->get('HTTP_HOST'); return $protocol . '://' . $host; } /** * Нормализация исходного URL (from) для сравнения */ private static function normalizeSourceUrl(string $url, string $baseUrl): string { // Если URL уже абсолютный if (preg_match('/^https?:\/\//', $url)) { return rtrim($url, '/'); } // Разбираем URL на путь и параметры $parsedUrl = parse_url($url); $path = $parsedUrl['path'] ?? ''; $query = $parsedUrl['query'] ?? ''; // Обрабатываем путь if (strpos($path, '/') === 0) { // Относительный от корня $parsedBase = parse_url($baseUrl); $normalized = $parsedBase['scheme'] . '://' . $parsedBase['host'] . $path; } else { // Относительный от текущей директории - используем базовый URL без параметров $baseWithoutParams = strtok($baseUrl, '?'); $basePath = parse_url($baseWithoutParams, PHP_URL_PATH); $baseDir = dirname($basePath === '/' ? '' : $basePath); $normalized = $baseWithoutParams . ($baseDir === '/' ? '' : $baseDir) . '/' . $path; } // Добавляем параметры если есть if ($query) { $normalized .= '?' . $query; } return rtrim($normalized, '/'); } /** * Нормализация целевого URL (to) для редиректа */ private static function normalizeTargetUrl(string $url): string { // Если URL уже абсолютный if (preg_match('/^https?:\/\//', $url)) { return $url; } $siteUrl = self::getSiteUrl(); // Разбираем URL на путь и параметры $parsedUrl = parse_url($url); $path = $parsedUrl['path'] ?? ''; $query = $parsedUrl['query'] ?? ''; // Обрабатываем путь if (strpos($path, '/') === 0) { $normalized = $siteUrl . $path; } else { // Для относительных путей используем текущий URL без параметров как базовый $currentUrl = self::getCurrentUrl(); $currentWithoutParams = strtok($currentUrl, '?'); $currentPath = parse_url($currentWithoutParams, PHP_URL_PATH); $currentDir = dirname($currentPath === '/' ? '' : $currentPath); $normalized = $siteUrl . ($currentDir === '/' ? '' : $currentDir) . '/' . $path; } // Добавляем параметры если есть if ($query) { $normalized .= '?' . $query; } return $normalized; } /** * Проверка, что два URL одинаковые */ private static function isSameUrl(string $url1, string $url2): bool { // Приводим к единому формату для сравнения $url1 = rtrim($url1, '/'); $url2 = rtrim($url2, '/'); return $url1 === $url2; } /** * Поиск совпадения для текущего URL */ private static function findRedirect(): ?array { $currentUrl = self::getCurrentUrl(); $siteUrl = self::getSiteUrl(); foreach (self::$redirects as $from => $to) { // Нормализуем исходный URL для сравнения $normalizedFrom = self::normalizeSourceUrl($from, $siteUrl); $normalizedCurrent = rtrim($currentUrl, '/'); // Сравниваем URL if ($normalizedFrom === $normalizedCurrent) { $normalizedTo = self::normalizeTargetUrl($to); return [ 'source' => $from, 'target' => $normalizedTo, 'original_target' => $to ]; } } return null; }
[RuntimeException] 
Could not start session because headers have already been sent. "/home/bitrix/ext_www/new.fesco/local/php_interface/include/redirectManager.php":1. (0)
/home/bitrix/ext_www/new.fesco/bitrix/modules/main/lib/session/session.php:151
#0: Bitrix\Main\Session\Session->start()
	/home/bitrix/ext_www/new.fesco/bitrix/modules/main/lib/session/kernelsessionproxy.php:47
#1: Bitrix\Main\Session\KernelSessionProxy->start()
	/home/bitrix/ext_www/new.fesco/bitrix/modules/main/include.php:180
#2: require_once(string)
	/home/bitrix/ext_www/new.fesco/bitrix/modules/main/include/prolog_before.php:19
#3: require_once(string)
	/home/bitrix/ext_www/new.fesco/bitrix/modules/main/include/prolog.php:10
#4: require_once(string)
	/home/bitrix/ext_www/new.fesco/bitrix/header.php:1
#5: require(string)
	/home/bitrix/ext_www/new.fesco/jp/about/index.php:2
----------