Перенаправление HTTP запросов в PHP: способы и примеры
Основные методы редиректа в PHP
Наиболее эффективный способ перенаправить пользователя на другую страницу в PHP - использование функции header() с параметром Location. Этот метод работает на уровне протокола HTTP и передаёт браузеру команду перейти по указанному адресу. После отправки заголовка необходимо вызвать exit или die, чтобы остановить выполнение скрипта и предотвратить дальнейшую отправку контента.
<?php
header('Location: https://example.com/new-page.php');
exit;
?>редирект php страниц (редирект страниц в php)
По умолчанию передаётся статус-код 302 Found (временное перенаправление). Для постоянного перенаправления нужно явно указать код 301 с помощью третьего параметра функции header() или константы true для замены предыдущего заголовка.
<?php
header('Location: https://example.com/permanent-page.php', true, 301);
exit;
?>
Данный подход применим для большинства сценариев: после авторизации, при смене структуры сайта, при обработке форм, а также для перенаправления на HTTPS. Основное преимущество - максимальная скорость и корректная индексация поисковыми системами при использовании правильного статус-кода.
Типичная ошибка: заголовки уже отправлены
Функция header() должна вызываться до любого вывода данных (включая пробелы, HTML или вывод через echo). Если до вызова header() произошёл вывод, появится предупреждение Cannot modify header information. Решение: проверить код на наличие лишнего вывода перед редиректом, использовать буферизацию вывода (ob_start()) или вызвать headers_sent() для определения возможности отправки заголовка.
Как сделать постоянный редирект (301) для SEO?
Постоянное перенаправление используется, когда страница навсегда перемещена на новый адрес. Поисковые системы передают вес ссылок на новый URL. Для реализации достаточно указать код 301 в header().
<?php
header('Location: https://example.com/new-location', true, 301);
exit;
?>
Важно также перенаправить все варианты URL (с www и без, HTTP и HTTPS) на канонический.
Проблема: неправильный код статуса
Если забыть указать третий параметр, по умолчанию будет 302, что может привести к потере ранжирования при постоянном переезде. Всегда проверяйте реальный код ответа с помощью инструментов разработчика или CURL.
Как выполнить редирект с задержкой (meta refresh)?
Иногда требуется показать пользователю сообщение перед перенаправлением. В этом случае используют HTML-мета-тег Refresh с указанием времени в секундах. Этот способ не является HTTP-редиректом, но поддерживается всеми браузерами.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Refresh" content="5; url=https://example.com/after-delay">
</head>
<body>
<p>Вы будете перенаправлены через 5 секунд.</p>
</body>
</html>
Также можно комбинировать с PHP: вывести страницу с сообщением и установить заголовок Refresh через header().
<?php
header('Refresh: 5; url=https://example.com/after-delay');
echo 'Перенаправление через 5 секунд...';
exit;
?>
Проблема: несовместимость с поисковыми системами
Meta refresh может неверно интерпретироваться поисковиками. Для постоянных редиректов рекомендуется HTTP-метод. Кроме того, при большом времени задержки пользователь может уйти.
Как сделать редирект через JavaScript, если PHP не может отправить заголовки?
В случаях, когда заголовки уже отправлены и невозможно использовать header(), применяют JavaScript-редирект через window.location. Этот метод выполняется на стороне клиента и не является надёжным для SEO, но может служить запасным вариантом.
<?php
if (headers_sent()) {
echo '<script>window.location.href="https://example.com/js-redirect";</script>';
} else {
header('Location: https://example.com/js-redirect');
}
exit;
?>
Дополнительно можно отобразить ссылку для ручного перехода в случае отключённого JavaScript.
Проблема: снижение безопасности и доступности
JavaScript-редирект не работает при отключённом скриптах и хуже обрабатывается поисковыми ботами. Следует применять только как временное решение.
Как настроить редирект через .htaccess (вне PHP)?
Хотя статья посвящена PHP, стоит упомянуть, что на сервере Apache редиректы можно задать через файл .htaccess с помощью модуля mod_rewrite. Это позволяет перенаправлять без нагрузки на PHP и часто используется для переезда сайта.
RewriteEngine On
RewriteRule ^old-page$ /new-page [R=301,L]
Такой редирект работает до выполнения PHP, что решает проблему с выводом заголовков.
Проблема: модуль mod_rewrite может быть отключён
Не все хостинги поддерживают mod_rewrite или разрешают изменение .htaccess. В таких случаях требуется PHP-редирект.
Расширенные примеры редиректов в PHP
Пример 1. Редирект в зависимости от HTTP-заголовка User-Agent
Перенаправление пользователей мобильных устройств на мобильную версию сайта.
<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (preg_match('/Mobile|Android|iPhone/i', $userAgent)) {
header('Location: https://m.example.com', true, 302);
exit;
}
// остальной код для десктопной версии
?>
Результат: при заходе с мобильного браузера будет выполнен редирект на m.example.com.
Заголовок ответа: HTTP/1.1 302 Found Location: https://m.example.com
Пример 2. Редирект после проверки аутентификации
Если пользователь не авторизован, его перенаправляют на страницу входа, а после логина возвращают обратно.
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
// сохраняем текущий URL для возврата
$_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI'];
header('Location: /login.php', true, 302);
exit;
}
?>
Результат: неавторизованный пользователь будет перенаправлен на /login.php, а после входа скрипт login.php может использовать сохранённый URL.
Запрос: GET /profile.php Ответ: 302 Found, Location: /login.php
Пример 3. Редирект с сохранением HTTP-метода (307 Temporary Redirect)
Если нужно перенаправить POST-запрос, чтобы данные формы были повторно отправлены на новый URL, используется статус 307.
<?php
header('Location: https://example.com/process-form', true, 307);
exit;
?>
Результат: браузер повторно отправит POST-запрос на новый адрес с теми же данными.
Запрос: POST /old-form.php Ответ: 307 Temporary Redirect, Location: /process-form Далее браузер делает POST /process-form с телом запроса.
Проблема: не все браузеры корректно поддерживают 307
Современные браузеры работают правильно. Однако для критичных данных лучше использовать обработку на стороне сервера.
Пример 4. Редирект на основе данных из базы данных (динамический)
Перенаправление со старых URL на новые, хранящиеся в БД (например, после реструктуризации).
<?php
$oldSlug = $_GET['slug'] ?? '';
$pdo = new PDO('mysql:host=localhost;dbname=site', 'user', 'pass');
$stmt = $pdo->prepare('SELECT new_url FROM redirects WHERE old_slug = ?');
$stmt->execute([$oldSlug]);
$row = $stmt->fetch();
if ($row) {
header('Location: ' . $row['new_url'], true, 301);
exit;
} else {
header('HTTP/1.1 404 Not Found');
echo 'Страница не найдена';
}
?>
Результат: при обращении к /page.php?slug=old-article будет выполнен 301 редирект на новый URL из БД.
Запрос: GET /page.php?slug=old-article Ответ: 301 Moved Permanently, Location: https://example.com/new-article
Пример 5. Редирект с протокола HTTP на HTTPS
Обеспечение безопасного соединения. Часто используется в начале скрипта.
<?php
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
$redirectUrl = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('Location: ' . $redirectUrl, true, 301);
exit;
}
?>
Результат: любой HTTP-запрос перенаправляется на соответствующий HTTPS-адрес.
Запрос: GET http://example.com/page Ответ: 301 Moved Permanently, Location: https://example.com/page
Проблема: бесконечный цикл при неправильной настройке
Если на сервере уже включено принудительное HTTPS через .htaccess или конфигурацию, PHP-редирект может конфликтовать. Следует отключать один из механизмов.
Пример 6. Редирект с параметрами (сохранение GET-параметров)
При перенаправлении на другой домен или поддомен нужно передать все существующие параметры.
<?php
$query = $_SERVER['QUERY_STRING'] ?? '';
$newUrl = 'https://new.example.com' . $_SERVER['REQUEST_URI'];
if (!empty($query)) {
$newUrl .= '?' . $query;
}
header('Location: ' . $newUrl, true, 301);
exit;
?>
Результат: запрос /old?page=2&sort=asc перейдёт на https://new.example.com/old?page=2&sort=asc.
Запрос: GET /old?page=2&sort=asc Ответ: 301, Location: https://new.example.com/old?page=2&sort=asc