Получение текущего URL в PHP: от простого к сложному

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

Способы получения текущего URL в PHP

Основное универсальное решение

Функция getCurrentUrl() собирает полный URL с учётом протокола, домена, порта, пути и строки запроса.

function getCurrentUrl(): string {
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    if (isset($_SERVER['REQUEST_SCHEME'])) {
        $scheme = $_SERVER['REQUEST_SCHEME'];
    }
    $host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';
    $port = '';
    if (isset($_SERVER['SERVER_PORT']) && 
        (($scheme === 'http' && $_SERVER['SERVER_PORT'] != 80) ||
         ($scheme === 'https' && $_SERVER['SERVER_PORT'] != 443))) {
        $port = ':' . $_SERVER['SERVER_PORT'];
    }
    $uri = $_SERVER['REQUEST_URI'] ?? '/';
    return $scheme . '://' . $host . $port . $uri;
}

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

Пошаговое объяснение:
1. Определяем протокол через переменную $_SERVER['HTTPS']. Если она не пуста и не равна 'off' – значит HTTPS.
2. Используем $_SERVER['REQUEST_SCHEME'] как альтернативный источник (доступен в Apache 2.4+).
3. Берём домен из HTTP_HOST (включает порт), но если его нет – из SERVER_NAME.
4. Порт добавляем только если он нестандартный (80 для HTTP, 443 для HTTPS).
5. Путь с query-строкой берётся из REQUEST_URI.
6. Собираем итоговую строку.

Возможные проблемы и их решения:

  • Переменная $_SERVER['HTTPS'] может отсутствовать (например, в некоторых конфигурациях FastCGI). Решение: проверить её через isset().
  • За прокси-сервером настоящий протокол может быть передан в заголовке X-Forwarded-Proto. Тогда нужно проверять $_SERVER['HTTP_X_FORWARDED_PROTO'], но это требует доверия к прокси.
  • Значение HTTP_HOST может содержать порт (например, example.com:8080). Если порт уже включён, его не следует дублировать. В решении выше порт отделяется, поэтому нужно либо разбирать HTTP_HOST, либо использовать SERVER_NAME. В примере использован HTTP_HOST как есть; если требуется убрать порт из хоста, нужно применить parse_url($host, PHP_URL_HOST).

Как получить только путь и строку запроса (без протокола и домена)?

$currentPath = $_SERVER['REQUEST_URI'];
echo $currentPath; // например: /blog/article?id=10

Php текущая url (текущая url в php)

Проблемы:

  • При использовании внутренних редиректов (например, при перезаписи в .htaccess) REQUEST_URI может содержать исходный запрос, а не конечный файл. Для получения физического пути используйте $_SERVER['SCRIPT_NAME'].
  • Если страница доступна через несколько маршрутов, значение может отличаться.

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

$urlWithoutQuery = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://' .
                 $_SERVER['HTTP_HOST'] . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
echo $urlWithoutQuery; // https://example.com/blog/article

Mobile php url (мобильный url в php)

Особенности:

  • Функция parse_url() корректно отсекает query. Если в пути есть фрагмент (#), он тоже отбрасывается.
  • При отсутсвии query вернётся тот же путь.

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

function getCurrentUrlBehindProxy(): string {
    $scheme = 'http';
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
        $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
    } elseif (!empty($_SERVER['HTTPS'])) {
        $scheme = 'https';
    }
    $host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? $_SERVER['HTTP_HOST'] ?? 'localhost';
    $uri = $_SERVER['REQUEST_URI'] ?? '/';
    return $scheme . '://' . $host . $uri;
}

Php open url (открытие url в php)

Риски:

  • Заголовки X-Forwarded-* могут быть подделаны клиентом. Используйте только если сервер доверяет прокси (настройка TrustedProxies в фреймворках).
  • Не все прокси передают порт отдельно. В таком случае порт может содержаться в HTTP_HOST.

Как получить URL, гарантированно совпадающий с тем, что видит пользователь (с учётом rewrite)?

// Использование $_SERVER['SCRIPT_URI'] (доступен в некоторых серверных API)
if (isset($_SERVER['SCRIPT_URI'])) {
    $url = $_SERVER['SCRIPT_URI'];  // полный URL от сервера
} else {
    $url = getCurrentUrl();
}

Js php url (javascript и php url)

Замечание:

  • $_SERVER['SCRIPT_URI'] генерируется сервером на основе фактических директив, но не всегда присутствует (отсутствует в IIS, некоторых конфигурациях Apache).
  • Не получить использовать во всех окружениях.

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

$currentUrl = filter_var(getCurrentUrl(), FILTER_SANITIZE_URL);
echo htmlspecialchars($currentUrl, ENT_QUOTES, 'UTF-8');

Безопасность:

  • Выводить URL без санитизации может привести к XSS-атакам, если злоумышленник передаёт вредоносные параметры.
  • Функция filter_var(..., FILTER_SANITIZE_URL) удаляет запрещённые символы, но не гарантирует безопасность при выводе. Всегда применяйте htmlspecialchars.
- Php url query (url-запрос (query string) в php)
- Include php url (включение url через include в php)
- Engine php url (движок url в php)

Дополнительные расширенные примеры работы с текущим URL

Пример 1: Извлечение компонентов URL с помощью regex

Пример
$url = getCurrentUrl();
// Извлекаем протокол, домен, порт, путь и query
preg_match('|^(https?://[^/]+)(?::(\d+))?(/.*?)(\?.*)?$|i', $url, $matches);
$components = [
    'base'     => $matches[1],
    'port'     => $matches[2] ?? '',
    'path'     => $matches[3],
    'query'    => $matches[4] ?? ''
];
print_r($components);
Array
(
    [base] => https://example.com
    [port] => 
    [path] => /blog/article
    [query] => ?id=10
)

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

Пример 2: Получение URL для CLI-скрипта (имитация веб-окружения)

Пример
// В командной строке $_SERVER отсутствует. Моделируем:
if (php_sapi_name() === 'cli') {
    $currentUrl = 'http://localhost' . ($argv[1] ?? '/');
    echo "URL (имитация): $currentUrl\n";
} else {
    echo "Веб-запрос, реальный URL: " . getCurrentUrl();
}
URL (имитация): http://localhost/test?param=1

Позволяет тестировать функции, работающие с URL, в консоли. Первым аргументом передаётся путь.

Пример 3: Сравнение производительности методов (micro-бенчмарк)

Пример
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    $url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
$end = microtime(true);
echo "Сборка строкой: " . ($end - $start) . " сек.\n";

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    $url = sprintf('%s://%s%s',
        (!empty($_SERVER['HTTPS']) ? 'https' : 'http'),
        $_SERVER['HTTP_HOST'],
        $_SERVER['REQUEST_URI']
    );
}
$end = microtime(true);
echo "sprintf: " . ($end - $start) . " сек.\n";
Сборка строкой: 0.042 сек.
sprintf: 0.039 сек.

Разница незначительная, но sprintf может быть читаемее. Для высоких нагрузок обычно не критично.

Пример 4: Обработка ситуации, когда сервер передаёт порт в HTTP_HOST (случай нестандартного порта)

Пример
$rawHost = $_SERVER['HTTP_HOST']; // например, example.com:8080
$parts = parse_url('http://' . $rawHost); // протокол не важен
$host = $parts['host'];
$port = isset($parts['port']) ? ':' . $parts['port'] : '';
$scheme = (!empty($_SERVER['HTTPS'])) ? 'https' : 'http';
$fullUrl = $scheme . '://' . $host . $port . $_SERVER['REQUEST_URI'];
echo $fullUrl;
http://example.com:8080/path?q=1

Важно, чтобы не было дублирования порта, если он уже в REQUEST_URI (редко).

Пример 5: Использование констант и переменных окружения для совместимости

Пример
// Некоторые CMS хранят базовый URL в конфигурации
define('BASE_URL', 'https://mysite.com');
// Функция получает относительный путь от корня домена
function getFullUrlRelative(): string {
    $base = BASE_URL;
    return $base . $_SERVER['REQUEST_URI'];
}
echo getFullUrlRelative();
https://mysite.com/blog/article?id=10

Подходит, когда домен фиксирован, нет необходимости динамически определять протокол. Минус - при смене домена или протокола придётся менять константу.

Пример 6: Получение URL с поддержкой альтернативных серверов (IIS, nginx)

Пример
if (isset($_SERVER['IIS_WasUrlRewritten'])) {
    // В IIS с включённой Rewrite может быть другая переменная
    $uri = $_SERVER['UNENCODED_URL'] ?? $_SERVER['REQUEST_URI'];
} else {
    $uri = $_SERVER['REQUEST_URI'];
}
$scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
echo $scheme . '://' . $host . $uri;

Этот код проверяет наличие специфичных серверных переменных, что повышает переносимость.

Пример 7: Извлечение query-параметров из текущего URL и их изменение

Пример
$url = getCurrentUrl();
$parsed = parse_url($url);
parse_str($parsed['query'] ?? '', $queryParams);
$queryParams['page'] = 2; // изменить параметр
$newQuery = http_build_query($queryParams);
$newUrl = $parsed['scheme'] . '://' . $parsed['host'] . $parsed['path'] . '?' . $newQuery;
echo $newUrl;
https://example.com/list?page=2&filter=active

Позволяет перестраивать URL с новыми параметрами, сохраняя порядок и кодировку.

Текущая URL в PHP - comments

En
Php текущая url (php)