Установка корневого URL в PHP: методы и примеры

Раздел: Веб-разработка на PHP -> Работа с URL в PHP

Определение базового URL в PHP

Базовый URL (корневой адрес) часто требуется для формирования абсолютных ссылок, редиректов, указания путей к ресурсам. В PHP нет встроенной константы, и разработчики собирают его из переменных сервера. Рассмотрим наиболее эффективное решение, а также альтернативные подходы.

Универсальная функция getBaseUrl()


function getBaseUrl() {
    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
        $protocol = $_SERVER['HTTP_X_FORWARDED_PROTO'];
    }
    $host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';
    $port = $_SERVER['SERVER_PORT'];
    $portSuffix = ($protocol === 'https' && $port == 443) || ($protocol === 'http' && $port == 80) ? '' : ':' . $port;
    $base = $protocol . '://' . $host . $portSuffix;
    $scriptName = $_SERVER['SCRIPT_NAME'];
    $dir = rtrim(dirname($scriptName), '/\\');
    $basePath = ($dir !== '.' && $dir !== '') ? $dir : '';
    return $base . $basePath;
}

Php создание ссылки (создание ссылки в php)

Код последовательно определяет протокол (с учётом возможного обратного прокси через заголовок X-Forwarded-Proto), хост, порт и путь до корня приложения. Если скрипт выполняется из подпапки вида /myapp/public/index.php, то базовый URL будет содержать /myapp (или /myapp/public в зависимости от точки входа). Рекомендуется использовать эту функцию как основу для проектов.

Типичные проблемы и их решения:

  • В CLI окружении переменные $_SERVER отсутствуют. Следует проверять php_sapi_name() и возвращать значение из конфигурации.
  • Подмена HTTP_HOST может привести к нежелательным URL. Рекомендуется валидировать хост (например, через белый список доменов).
  • Если веб-сервер использует внутренние редиректы или rewriting, значение SCRIPT_NAME может не совпадать с реальным URL-путем. В таких случаях лучше использовать SCRIPT_URI или задавать базовый путь явно.

Как задать базовый URL статически в конфигурации?

Если домен и путь фиксированы, проще определить константу. Это исключает вычисления при каждом запросе.


define('BASE_URL', 'https://example.com/myapp/');

Js php url (javascript и php url)

Цель:

Упрощение кода, повышение производительности. Используется в небольших проектах или приложениях с единственным доменом.

При переносе на другой домен или подпапку необходимо менять конфиг. Не подходит для мультисайтовой архитектуры.

Как быстро получить базовый URL, игнорируя протокол и порт?

Можно взять только HTTP_HOST и добавить 'http://'.


$baseUrl = 'http://' . $_SERVER['HTTP_HOST'];

Php url (url в php)

Цель:

Минимальный код, когда протокол и порт не принципиальны (например, для разработки).

Не учитывает HTTPS, поэтому на production может создавать смешанный контент. Также игнорирует подпапки.

Как задать базовый URL в HTML через тег base?

Внутри шаблона можно указать тег <base href='...'>.


<base href='<?php echo getBaseUrl(); ?>/'>

Url form php (url формы в php)

Цель:

Все относительные ссылки в документе будут разрешаться относительно этого адреса. Удобно для статических ресурсов.

Работает только на стороне клиента. При использовании AJAX или PHP редиректов по-прежнему требуется серверный базовый URL.

Как использовать переменную SCRIPT_URI для получения базового URL?

Если сервер предоставляет SCRIPT_URI (например, Apache с mod_rewrite), можно разобрать её через parse_url.


if (isset($_SERVER['SCRIPT_URI'])) {
    $parts = parse_url($_SERVER['SCRIPT_URI']);
    $base = $parts['scheme'] . '://' . $parts['host'];
    if (isset($parts['port'])) $base .= ':' . $parts['port'];
    $base .= rtrim(dirname($parts['path']), '/');
} else {
    // fallback
}

Php url query (url-запрос (query string) в php)

Цель:

Получить точный URL, сформированный сервером.

Переменная SCRIPT_URI доступна не во всех конфигурациях. Даёт путь до скрипта, а не до корня приложения (нужно обрезать до директории).

Как определить базовый URL, используя документ-рут и файловую систему?

Можно вычислить относительный путь от DOCUMENT_ROOT до текущего файла и скомбинировать с доменом.


$docRoot = $_SERVER['DOCUMENT_ROOT'];
$scriptDir = dirname(__FILE__);
$relative = str_replace($docRoot, '', $scriptDir);
$baseUrl = 'http://example.com' . $relative . '/';

Цель:

Полезно, когда требуется узнать путь, не полагаясь на SCRIPT_NAME (например, при симлинках).

Требует заранее известного домена. Не работает, если документ-рут не совпадает с корнем сайта (например, при алиасах).
- Url class php (класс url в php)
- Mobile php url (мобильный url в php)
- Php параметр url (параметры url в php)

Пример 1: Учет обратного прокси с доверенными IP

Пример

function getBaseUrlWithProxyCheck() {
    $trustedProxies = ['10.0.0.1', '172.16.0.0/12'];
    $clientIP = $_SERVER['REMOTE_ADDR'];
    $useProxy = false;
    if (in_array($clientIP, $trustedProxies)) {
        $useProxy = true;
    }
    if ($useProxy) {
        $proto = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? 'http';
        $host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? $_SERVER['HTTP_HOST'];
        $port = $_SERVER['HTTP_X_FORWARDED_PORT'] ?? $_SERVER['SERVER_PORT'];
    } else {
        $proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        $port = $_SERVER['SERVER_PORT'] ?? 80;
    }
    $portSuffix = ($proto === 'https' && $port == 443) || ($proto === 'http' && $port == 80) ? '' : ':' . $port;
    $base = $proto . '://' . $host . $portSuffix;
    $scriptName = $_SERVER['SCRIPT_NAME'] ?? '';
    $basePath = rtrim(dirname($scriptName), '/\\');
    if ($basePath === '.' || $basePath === '\\') $basePath = '';
    return $base . $basePath;
}
echo getBaseUrlWithProxyCheck();
https://app.example.com/subdir (хост и протокол из заголовков, если IP доверенный)

Пример показывает, как безопасно учитывать заголовки прокси только от доверенных серверов. Без такой проверки клиент может подменить X-Forwarded-Host.

Пример 2: Базовый URL при многосайтовости с подстановкой имени приложения

Пример

$currentSite = 'site1';
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$baseUrl = $scheme . '://' . $host . '/' . $currentSite . '/';
if (isset($_SERVER['SERVER_PORT'])) {
    $port = (int)$_SERVER['SERVER_PORT'];
    if (($scheme === 'https' && $port !== 443) || ($scheme === 'http' && $port !== 80)) {
        $baseUrl = $scheme . '://' . $host . ':' . $port . '/' . $currentSite . '/';
    }
}
echo $baseUrl;
http://example.com/site1/

Для мультисайтовой архитектуры базовый URL динамически формируется на основе имени сайта, что удобно при развертывании.

Пример 3: Извлечение базового URL с помощью parse_url() из полного URL запроса

Пример

$requestUrl = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$parts = parse_url($requestUrl);
$scheme = $parts['scheme'];
$host = $parts['host'];
$port = isset($parts['port']) ? ':' . $parts['port'] : '';
$baseUrl = $scheme . '://' . $host . $port;
echo $baseUrl;
http://example.com:8080

Этот приём использует REQUEST_URI, который включает полный путь и строку запроса. parse_url разбирает его, и берется только схема, хост и порт. Недостаток: не добавляется базовый путь, если приложение лежит в подпапке (потребуется дополнительное извлечение из пути).

Пример 4: Базовый URL для приложения с единой точкой входа (front controller)

Пример

$scriptName = $_SERVER['SCRIPT_NAME'];
$basePath = rtrim(dirname($scriptName), '/');
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$baseUrl = $protocol . '://' . $host . $basePath;
$port = $_SERVER['SERVER_PORT'] ?? 80;
if (($protocol === 'https' && $port != 443) || ($protocol === 'http' && $port != 80)) {
    $baseUrl .= ':' . $port;
}
echo $baseUrl;
https://example.com/app

Этот пример подходит для фреймворков, где точка входа находится в подпапке, и все URL строятся относительно неё.

Пример 5: Использование конфигурационного файла .env для базового URL

Пример

$appUrl = getenv('APP_URL');
if (!$appUrl) {
    $appUrl = getBaseUrl();
}
echo $appUrl;
http://localhost:8080/myapp

Хранение базового URL в переменных окружения позволяет легко менять его для разных сред (dev, staging, prod) без изменения кода.

Базовый URL в PHP - comments

En
Php base url (php)