Как получить полный URL текущей страницы в PHP?
Полное решение: универсальная функция для получения URL
Проблема, которую вы описали, действительно частая среди новичков. Главные сложности — определение протокола (HTTP/HTTPS), учёт порта и корректная обработка всех суперглобальных переменных. Вот надёжное решение, которое работает на 99% серверов:
function getFullUrl() {
// Определяем протокол
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443
? 'https://'
: 'http://';
// Получаем домен (с портом, если он нестандартный)
$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';
// Получаем путь и GET-параметры
$uri = $_SERVER['REQUEST_URI'] ?? '/';
// Собираем URL
return $protocol . $host . $uri;
}
echo getFullUrl(); // Пример: https://example.com/page.php?id=5
Подробное объяснение
Разберём каждый шаг:
- Протокол: Проверяем
$_SERVER['HTTPS']. Если он равен 'on' (или не 'off'), то используем HTTPS. Дополнительно проверяем порт 443 — это стандартный порт HTTPS. Это нужно для случаев, когда$_SERVER['HTTPS']не определён (например, на некоторых хостингах или при обратном прокси). - Домен: Используем
$_SERVER['HTTP_HOST']— он уже включает порт, если он нестандартный (например,localhost:8080). Если эта переменная пуста, падаем на$_SERVER['SERVER_NAME'], а в крайнем случае — на 'localhost'. - Путь:
$_SERVER['REQUEST_URI']содержит путь и все GET-параметры (например,/folder/page.php?id=5&name=test).
Улучшенная версия с учётом прокси
Если ваш сайт работает за обратным прокси (например, Nginx, Cloudflare), стандартные переменные могут быть недоступны. Добавьте проверку заголовков:
function getFullUrl() {
// Определяем протокол через заголовки прокси (если есть)
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$protocol = $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https://' : 'http://';
} else {
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443
? 'https://'
: 'http://';
}
// Домен: сначала проверяем заголовки прокси
$host = $_SERVER['HTTP_X_FORWARDED_HOST']
?? $_SERVER['HTTP_HOST']
?? $_SERVER['SERVER_NAME']
?? 'localhost';
$uri = $_SERVER['REQUEST_URI'] ?? '/';
return $protocol . $host . $uri;
}
Важные замечания
- Не используйте
$_SERVER['SERVER_PORT']в URL, если порт стандартный (80 для HTTP, 443 для HTTPS) — это создаст лишние символы.$_SERVER['HTTP_HOST']уже содержит порт только в нестандартных случаях. - Всегда проверяйте существование ключей массива
$_SERVERчерез??(null coalescing operator), чтобы избежать ошибок на разных серверах. - Для абсолютной надёжности можно использовать класс
Symfony\Component\HttpFoundation\Request, если вы работаете с фреймворком. Но для чистого PHP приведённая функция — золотой стандарт.
Альтернативный подход: использование фильтров и parse_url
Если вам нужно не просто вывести URL, а разобрать его на части или проверить валидность, можно использовать комбинацию filter_var и parse_url. Этот способ удобен, когда вы строите URL из отдельных компонентов:
function buildFullUrl() {
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$port = $_SERVER['SERVER_PORT'] ?? 80;
// Собираем URL через parse_url и фильтр
$url = $scheme . '://' . $host;
if (($scheme === 'http' && $port != 80) || ($scheme === 'https' && $port != 443)) {
$url .= ':' . $port;
}
$url .= $_SERVER['REQUEST_URI'] ?? '/';
// Фильтруем для безопасности
return filter_var($url, FILTER_VALIDATE_URL) ? $url : false;
}
$url = buildFullUrl();
if ($url) {
echo "Полный URL: " . $url;
} else {
echo "Не удалось собрать корректный URL";
}
Плюсы: filter_var проверяет, что URL действительно валидный — это защищает от ошибок, если $_SERVER содержит мусор. Минусы: Метод может отбрасывать некоторые корректные URL (например, с кириллическими доменами в Punycode). Используйте этот вариант, если вам важна безопасность, а не универсальность.
Ответов пока нет.
Войдите чтобы оставить ответ