Как сделать редирект в PHP
<?php
header('Location: /catalog.php');
exit;header('Location: …') отправляет браузеру заголовок «иди по этому адресу», и браузер сразу открывает новую страницу. Адрес может быть путём на своём сайте (/catalog.php) или полным адресом (https://example.com/page).
exit после header обязателен. Без него PHP выполнит файл до конца, и всё, что идёт ниже, уйдёт браузеру. Для закрытой страницы это значит, что её содержимое получит любой — просто не увидит в браузере из-за перенаправления, а программа для скачивания страниц увидит.
Какой код ответа выбрать
По умолчанию Location отправляется с кодом 302 — «временно перемещено». Другой код задают третьим аргументом:
<?php
header('Location: https://example.com/new-page', true, 301);
exit;| Код | Когда |
|---|---|
| 301 | страница переехала насовсем; поисковики переносят адрес в выдаче на новый |
| 302 | временное перенаправление: на вход, на выбранный язык |
| 303 | после обработки формы POST — на страницу результата |
| 307, 308 | как 302 и 301, но браузер повторит тот же метод (POST останется POST) |
Браузер запоминает 301 надолго. Проверяйте перенаправление сначала с 302 и меняйте на 301, когда всё работает: ошибочный постоянный редирект у посетителей потом трудно отменить.
Редирект после формы
После успешной отправки формы перенаправляйте посетителя, чтобы обновление страницы (F5) не отправило данные повторно:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// проверка и сохранение данных…
header('Location: /thanks.php', true, 303);
exit;
}Полный пример — в справке Как отправить форму на ту же страницу.
Редирект не работает
- Ошибка
Cannot modify header information - headers already sent— доheader()уже был вывод: HTML,echo, пробел перед<?php. Разбор — в справке headers already sent. - Страница не перенаправляет и ошибок не видно — включите показ ошибок (справка Как включить вывод ошибок): скорее всего, это та же причина.
- Перенаправление по кругу («слишком много переадресаций» в браузере) — страница отправляет на адрес, который снова отправляет обратно. Проверьте условия: например,
login.phpне должна перенаправлять на саму себя.
Адрес от посетителя
Не перенаправляйте на адрес, который пришёл из формы или ссылки, без проверки: header('Location: ' . $_GET['back']). Злоумышленник пришлёт ссылку на ваш сайт, которая уведёт посетителя на поддельную страницу входа, — это «открытый редирект».
Безопасно принимать только путь своего сайта:
<?php
$back = $_GET['back'] ?? '/';
$isLocal = is_string($back)
&& str_starts_with($back, '/')
&& !str_starts_with($back, '//')
&& !str_contains($back, '\\');
if (!$isLocal) {
$back = '/';
}
header('Location: ' . $back);
exit;Путь должен начинаться с одной косой черты и не содержать обратной: адреса //example.com и /\example.com браузер понял бы как переход на другой сайт. Проверка is_string нужна потому, что вместо строки в адресе можно передать массив (?back[]=1).
Перенаправить весь сайт
Перевод всего сайта с http на https или с www на адрес без www удобнее делать в настройках веб-сервера или в панели хостинга, а не в каждом PHP-файле: такое правило срабатывает до PHP и для всех файлов сразу.