Интернет не прощает исчезновения. Каждая страница, каждый URL — это не просто адрес, а обещание, что по этой ссылке кто-то найдёт то, что искал. Что информация, однажды опубликованная, останется доступной. Что доверие, вложенное в вас пользователем или другим сайтом, не будет нарушено.
Но сайты меняются. Структура эволюционирует. Домены переезжают. Страницы объединяются, удаляются, перерождаются. И в этот момент возникает выбор: оставить за собой след из мёртвых ссылок и ошибок 404 — или честно проводить каждого, кто пришёл по старому адресу, к новому месту.
Именно для этого существует редирект. Не как техническая формальность. Не как «SEO-фишка». А как акт цифровой этики.
В PHP этот акт реализуется одной из самых простых, но самых ответственных функций — header(). Она не требует плагинов, не зависит от CMS, не нуждается в .htaccess. Она говорит с браузером напрямую, на языке HTTP, и сообщает прямо: «Ресурс переместился. Вот его новое место». И от того, как вы её используете — с пониманием или наобум, — зависит, сохраните ли вы доверие или оставите пользователей в пустоте.
Прежде всего, давайте избавимся от иллюзий. Редирект — это не «PHP перекидывает пользователя». Это HTTP-механизм, который PHP лишь инициирует. Когда вы вызываете header(«Location: …»), вы не управляете браузером. Вы отправляете ему заголовок, как часть HTTP-ответа. И браузер, получив этот заголовок, сам решает: «Ага, сервер говорит, что ресурс переместился. Пойду по новому адресу».
Это важно понимать, потому что оно определяет границы возможного. Вы не можете заставить браузер сделать то, что он не умеет. Вы не можете отменить редирект после отправки заголовка. Вы не можете показать сообщение «Подождите, вы будете перенаправлены…» и одновременно отправить Location — потому что браузер, получив заголовок, немедленно уйдёт.
Редирект — это диалог по правилам. И правила эти заданы спецификацией HTTP, а не вашим желанием.
В HTTP существует множество кодов перенаправления, но для веб-разработчика реально важны два:
- 301 Moved Permanently — постоянное перемещение.
- 302 Found (ранее Temporary Redirect) — временное перемещение.
Эти коды несут семантическую нагрузку, которую понимают не только браузеры, но и поисковые системы, кэширующие прокси, API-клиенты и даже боты.
Когда вы отправляете 301, вы говорите миру: «Этот URL больше никогда не будет использоваться. Всё, что было здесь, теперь здесь — и навсегда». Поисковики принимают это всерьёз: они удаляют старый URL из индекса, передают его вес новому, обновляют сниппеты. Это правильный выбор при смене домена, реорганизации структуры, объединении страниц.
Когда вы отправляете 302, вы говорите: «Сейчас ресурс временно по другому адресу, но скоро вернётся». Поисковики не удаляют старый URL. Они не передают вес. Они просто показывают новый контент, но помнят, что оригинал — где-то ещё. Это уместно при технических работах, A/B-тестировании, сезонных акциях.
И вот здесь рождается главная ошибка: использовать 302 там, где нужен 301. Многие делают так «на всякий случай», «чтобы потом можно было вернуть». Но это вредит SEO. Потому что поисковик не знает, что вы «потом вернёте». Он видит: «Страница постоянно перенаправляется, но не навсегда». И начинает сомневаться в её стабильности. А сомнение — враг ранжирования.
Поэтому перед тем, как писать код, задайте себе вопрос: это навсегда или временно? Ответ на него определит не только цифру в коде, но и будущее вашего контента.
Как работает header() — и почему порядок имеет значение
Функция header() в PHP — простая, но хрупкая, она отправляет HTTP-заголовок. Но HTTP требует, чтобы все заголовки шли до тела ответа. Это фундаментальное правило протокола.
В PHP это означает: никакого вывода до вызова header(). Ни echo, ни print, ни HTML-тега, ни даже пробела перед <?php. Ничего. Потому что в момент, когда PHP отправляет первый байт контента, он автоматически отправляет заголовки (включая статус 200 OK) — и после этого уже нельзя менять Location.
Если вы нарушите это правило, получите ошибку:
Warning: Cannot modify header information — headers already sent
Это не «глюк PHP». Это защита от некорректного HTTP. И вместо того чтобы бороться с ней, нужно принять её как данность.
Как этого избежать?
— Пишите логику редиректа в самом начале скрипта.
— Убедитесь, что в файле нет BOM (Byte Order Mark) — скрытых байтов в начале UTF-8 файла.
— Не используйте include или require до редиректа, если в подключаемых файлах есть вывод.
— Включите буферизацию вывода (ob_start()), если вы не уверены в порядке операций (но это костыль, а не решение).
И помните: после header() всегда ставьте exit();. Почему? Потому что PHP продолжит выполнять скрипт, даже если вы уже отправили редирект. А это может привести к утечке данных, двойной отправке форм, неожиданному поведению. exit() — это точка останова. Это «всё, что дальше — не имеет значения».
Синтаксис: как правильно написать Location
Стандарт требует, чтобы значение заголовка Location было абсолютным URI. То есть включало схему (http:// или https://) и домен.
Но на практике все браузеры поддерживают и относительные пути:
header(«Location: /new-page.php»);
Это удобно, но рискованно. Потому что:
- Некоторые HTTP-клиенты (например, cURL без настроек) могут не обработать относительный редирект.
- Если сайт доступен и по HTTP, и по HTTPS, относительный путь сохранит текущую схему — что может привести к смешанному контенту или утечке данных.
Поэтому лучшая практика — всегда использовать абсолютный URL с явным протоколом:
header(«Location: https://example.ru/new-page.php», true, 301);
exit();
Обратите внимание на второй параметр — true. Он говорит PHP заменить любой ранее установленный заголовок Location, а не добавить новый. Это важно, если в скрипте возможны несколько условий редиректа.
Третий параметр — HTTP-статус. Без него PHP по умолчанию отправит 302. Чтобы отправить 301, его нужно указать явно.
Редирект с задержкой: когда это оправдано
Иногда хочется показать пользователю сообщение: «Вы будете перенаправлены через 5 секунд». И в PHP для этого есть соблазн использовать sleep(5) перед header().
Но это ошибка. Потому что:
- Браузер не покажет сообщение — он получит заголовок и сразу уйдёт.
- Если вы сначала выведете HTML с таймером, а потом попытаетесь отправить header() — получите ошибку «headers already sent».
- Поисковые роботы не ждут. Они увидят 200 OK и контент, а редирект проигнорируют.
Если вам действительно нужна задержка с сообщением — делайте это на клиенте, через HTML и JavaScript:
<p>Вы будете перенаправлены через 5 секунд…</p>
<script>
setTimeout(() => {
window.location.href = «https://example.ru/new-page.php»;
}, 5000);
</script>
Или через мета-тег:
<meta http-equiv=»refresh» content=»5; url=https://example.ru/new-page.php»>
Но помните: и то, и другое — не HTTP-редирект. Это клиентские решения. Они не передают SEO-вес. Они не работают без JavaScript или в старых браузерах. Их стоит использовать только для интерактивных сценариев, где важен пользовательский опыт, а не индексация.
В PHP редирект должен быть мгновенным, чистым и однозначным.
Где размещать код редиректа
Часто советуют «вставлять в index.php». Но это упрощение. На самом деле, место зависит от логики приложения.
- Если вы перенаправляете всю страницу — да, в начало основного скрипта.
- Если редирект зависит от условия (например, неавторизованный пользователь пытается зайти в админку) — он должен быть в том месте, где проверяется это условие.
- Если вы мигрируете старые URL — лучше вынести логику в отдельный файл или middleware, чтобы не засорять основной код.
Главное правило: редирект должен быть там, где принимается решение о том, что пользователь должен быть перенаправлен.
Почему редирект в PHP — не всегда лучший выбор
Несмотря на всю его простоту, редирект через PHP имеет ограничения:
- Он требует запуска интерпретатора PHP, что тратит ресурсы сервера.
- Он работает только для запросов, которые обрабатываются PHP-скриптом.
- Он не сработает, если файл не существует (например, старый URL вёл на несуществующий .html).
В таких случаях лучше использовать редирект на уровне веб-сервера — через .htaccess (Apache) или конфигурацию server (Nginx). Там редирект происходит до запуска PHP, быстрее и эффективнее.
Но если вы не имеете доступа к серверной конфигурации (например, на shared-хостинге), или редирект зависит от динамических данных (например, язык пользователя, статус подписки), — PHP остаётся единственным честным вариантом.
Этическое измерение редиректа
Каждый раз, когда вы удаляете страницу без редиректа, вы обманываете:
- пользователя, который сохранил ссылку,
- автора, который на вас сослался,
- поисковик, который доверил вам трафик.
Каждый раз, когда вы настраиваете 301-редирект, вы говорите: «Я уважаю ваше время. Я ценю ваше доверие. Я не позволю информации исчезнуть».
Именно поэтому редирект — это обязанность любого, кто создаёт контент в интернете.
PHP даёт вам простой, прямой и мощный инструмент для выполнения этой обязанности.








