PHP URI: получение текущего адреса строки запроса

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

Получение URI в PHP: основные подходы

Основной способ получения текущего URI

Наиболее надёжным методом является использование суперглобального массива $_SERVER['REQUEST_URI']. Он содержит путь запроса вместе с query-строкой (если она есть). Однако значение может быть неэкранированным и содержать потенциально опасные символы, поэтому его нужно обрабатывать.

$uri = $_SERVER['REQUEST_URI'] ?? '/';
$uri = filter_var($uri, FILTER_SANITIZE_URL);
$parts = parse_url($uri);

Php проверить ссылку (проверить ссылку в php)

После этого можно получить отдельные компоненты: путь ($parts['path']), query ($parts['query']), фрагмент ($parts['fragment']).

Проблема: XSS через неэкранированный URI

Если выводить URI или его части в HTML без экранирования, возможна межсайтовая атака. Решение - всегда применять htmlspecialchars() перед выводом.

Как получить URI без query-параметров?

Иногда нужен только путь (без GET-параметров). Можно использовать strtok() или parse_url() с флагом PHP_URL_PATH:

$path = strtok($_SERVER['REQUEST_URI'], '?');
// или
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

Id ссылки php (идентификатор ссылки в php)

Проблема: пустой path при корне

Если запрос идёт к корню (/), parse_url вернёт пустую строку. Рекомендуется использовать условие $path = $path ?: '/';.

Как составить полный URI (схема, хост, порт)?

$_SERVER['REQUEST_URI'] содержит только путь. Для сборки абсолютного URI нужно добавить протокол, домен и порт. Пример:

$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$port = $_SERVER['SERVER_PORT'];
$uri = $_SERVER['REQUEST_URI'];
$fullUri = $protocol . '://' . $host . ($port != 80 && $port != 443 ? ':' . $port : '') . $uri;

активная ссылка php (создание активной ссылки в php)

Проблема: неверный порт при reverse proxy

За балансировщиком нагрузки или прокси реальный порт может быть передан через заголовок X-Forwarded-For или X-Forwarded-Port. Для точности нужно обрабатывать эти заголовки, но с осторожностью (доверять только из внутренней сети).

Как получить URI в консольном скрипте (CLI)?

Для скриптов командной строки суперглобальные переменные HTTP-запроса отсутствуют. URI можно передать как аргумент:

// php script.php /some/path?foo=bar
$uri = $argv[1] ?? '/';
// или использовать getopt() для более сложной обработки

Php ссылки (работа с url и ссылками в php)

Проблема: отсутствие стандарта

Нет единого способа - все зависит от соглашений в проекте. Рекомендуется задокументировать ожидаемый формат.

Как обработать URI при rewrite (nginx, Apache)?

После rewrite $_SERVER['REQUEST_URI'] может содержать изменённый путь, а исходный - $_SERVER['REDIRECT_URL'] или $_SERVER['ORIGINAL_PATH_INFO'] (в Apache). Пример проверки:

$uri = $_SERVER['REQUEST_URI'];
if (isset($_SERVER['REDIRECT_URL'])) {
    $uri = $_SERVER['REDIRECT_URL'];
}

Проблема: неполная совместимость

Ключи массивов зависят от конфигурации веб-сервера. Для портируемости лучше использовать $_SERVER['REQUEST_URI'] как единую точку входа.

- Php page url (url текущей страницы в php)

Расширенные примеры работы с URI в PHP:

Пример 1. Извлечение домена из URI

Пример
$fullUri = 'https://user:pass@example.com:8080/path?query=val#frag';
$components = parse_url($fullUri);
echo $components['host']; // example.com
echo $components['scheme']; // https
echo $components['port']; // 8080
example.com
https
8080

Пояснение: parse_url разбирает абсолютный URI на части. Для относительных URI схема и хост будут отсутствовать.

Пример 2. Сборка URI из компонентов

Пример
$parts = [
    'scheme' => 'https',
    'host'   => 'example.com',
    'path'   => '/api/v1/resource',
    'query'  => 'id=42&limit=10',
    'fragment' => 'section1'
];
$uri = http_build_url($parts); // требует PECL extension 'http'
// или ручная сборка:
$uri = $parts['scheme'] . '://' . $parts['host'] . $parts['path'];
$uri .= '?' . $parts['query'];
$uri .= '#' . $parts['fragment'];
echo $uri;
https://example.com/api/v1/resource?id=42&limit=10#section1

Пояснение: ручная сборка полезна при отсутствии расширения. Важно правильно закодировать query-строку с помощью http_build_query().

Пример 3. Обработка URI в многобайтовых кодировках

Пример
// URI может содержать не ASCII символы (например, кириллица)
$uri = '/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80?name=%D0%98%D0%B2%D0%B0%D0%BD';
$decodedUri = rawurldecode($uri);
echo $decodedUri; // /пример?name=Иван
// Для безопасного вывода:
echo htmlspecialchars($decodedUri, ENT_QUOTES, 'UTF-8');
/пример?name=Иван

Пояснение: rawurldecode корректно раскодирует процентную последовательность. Отличие от urldecode - не интерпретирует '+' как пробел, что правильно для пути.

Пример 4. Получение URI из внешнего запроса (cURL)

Пример
$ch = curl_init('https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
// Извлечение URI перенаправления:
preg_match('/^Location: (.+)$/im', $header, $matches);
$redirectUri = $matches[1] ?? null;
echo $redirectUri;
curl_close($ch);
https://api.example.com/redirected

Пояснение: при выполнении внутренних HTTP-запросов часто нужно извлечь URI из ответа, например, для обработки редиректов.

Пример 5. Использование filter_var для валидации URI

Пример
$userInput = 'http://example.com/path with spaces';
$sanitized = filter_var($userInput, FILTER_SANITIZE_URL);
echo $sanitized; // http://example.com/path%20with%20spaces
$valid = filter_var($sanitized, FILTER_VALIDATE_URL);
var_dump($valid); // false, потому что нет query? - на самом деле валидный
http://example.com/path%20with%20spaces
bool(false)

Пояснение: FILTER_VALIDATE_URL довольно строгий - не пропускает относительные пути и требует схему. Для проверки локальных URI лучше использовать parse_url() и собственную логику.

Пример 6. Работа с фрагментом (#) на клиенте

Пример
// Фрагменты не передаются на сервер в HTTP-запросе
// Но можно получить их через JavaScript и отправить через Ajax
// В PHP для входящих запросов $_SERVER['REQUEST_URI'] не содержит #
$uri = $_SERVER['REQUEST_URI'];
echo preg_replace('/#.*/', '', $uri); // удаление фрагмента, если каким-то образом попал

Пояснение: фрагмент обрабатывается только браузером, поэтому серверный код не может его получить стандартными средствами.

Получение URI в PHP - comments

En
Php uri (php)