Перенаправление HTTP запросов в PHP: способы и примеры

Раздел: Работа с HTTP -> Перенаправления

Основные методы редиректа в 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

Редирект страниц в PHP - comments

En
редирект php страниц (php)