Avatar ·

Как сделать редирект (перенаправление) в PHP?

Всем привет! Я только начал изучать PHP и столкнулся с проблемой. Пишу простой сайт с авторизацией. После того как пользователь успешно входит в систему, я хочу перенаправить его на страницу личного кабинета. Но у меня ничего не работает. Вот мой код (упрощённый): ```php ``` Когда я запускаю этот код, вместо редиректа я вижу сообщение "Вы будете перенаправлены..." и страница не переходит. В чём может быть проблема? Я слышал про какие-то коды состояния, например 301 или 302. Нужно ли их указывать? И обязательно ли писать `exit` после `header()`? Буду благодарен за подробное объяснение, так как в документации много непонятных моментов. Теги: php, http-redirect, http-status-code-301 <<>>

Основная причина проблемы: вывод до header()

Ваш код не работает, потому что функция header() должна вызываться до любого вывода в браузер. В вашем примере вы не выводили ничего явно, но проблема может быть в невидимых пробелах или BOM (Byte Order Mark) в файле. Даже один пробел перед <?php или пустая строка после ?> вызовут ошибку "Cannot modify header information".

Правильный синтаксис редиректа в PHP

Базовая конструкция выглядит так:

<?php
header('Location: https://example.com/new-page.php');
exit;
?>

Важные моменты:

  • Абсолютный или относительный URL: Можно использовать как полный URL (https://...), так и относительный (/dashboard.php). Рекомендуется использовать абсолютный, чтобы избежать проблем на разных поддоменах.
  • HTTP-статус код: По умолчанию PHP отправляет статус 302 (временный редирект). Если вам нужен постоянный редирект (например, для SEO при смене URL), используйте header('HTTP/1.1 301 Moved Permanently'); перед Location.
  • exit после header(): Обязательно вызывайте exit или die() после header('Location: ...'). Иначе скрипт продолжит выполнение, и пользователь может увидеть часть контента до того, как сработает редирект.

Пример с разными HTTP-статусами

<?php
// Временный редирект (302) — по умолчанию
header('Location: https://example.com/temp-page.php');
exit;

// Постоянный редирект (301) — для поисковиков
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://example.com/new-permanent-url.php');
exit;

// Редирект с задержкой (не рекомендуется, но иногда нужно)
header('Refresh: 5; url=https://example.com/delayed-page.php');
echo "Вы будете перенаправлены через 5 секунд...";
exit;
?>

Как избежать ошибок с выводом

Чтобы гарантированно избежать проблем:

  1. Убедитесь, что в PHP-файле нет пробелов или пустых строк до <?php и после ?>.
  2. Если ваш файл содержит только PHP-код, не закрывайте тег ?> в конце — это предотвратит случайный вывод пробелов.
  3. Используйте функцию ob_start() в начале скрипта для буферизации вывода — тогда header() можно вызывать даже после HTML-кода (но это костыль, лучше сразу писать правильно).

Проверка наличия вывода

Если вы не уверены, был ли уже вывод, используйте:

<?php
if (!headers_sent()) {
    header('Location: /dashboard.php');
    exit;
} else {
    // Альтернатива: JavaScript или HTML-редирект
    echo '<script>window.location.href="/dashboard.php";</script>';
    exit;
}
?>

Этот подход полезен, когда вы не контролируете весь код (например, подключаете сторонние библиотеки).

Полный рабочий пример для вашей задачи

<?php
// login.php
session_start();

// Проверка учётных данных (упрощённо)
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';

if ($username === 'admin' && $password === '12345') {
    $_SESSION['user'] = $username;
    header('Location: /dashboard.php');
    exit;
} else {
    header('Location: /login.php?error=1');
    exit;
}
?>
<<>>

Альтернативный подход: редирект через JavaScript или HTML

Если вы не можете использовать header() (например, из-за уже отправленного контента или ограничений хостинга), можно применить клиентские методы. Они менее надёжны, но работают как запасной вариант.

1. JavaScript-редирект

<?php
echo '<script>window.location.href = "/dashboard.php";</script>';
exit;
?>

Этот метод выполняется на стороне клиента, поэтому пользователь может отключить JavaScript. Также поисковые системы могут его не обработать.

2. HTML-мета-редирект

<?php
echo '<meta http-equiv="refresh" content="0; url=/dashboard.php">';
exit;
?>

Работает даже при отключённом JavaScript, но считается устаревшим для SEO. Задержка (в секундах) указывается в атрибуте content.

3. Комбинированный подход

<?php
if (!headers_sent()) {
    header('Location: /dashboard.php');
    exit;
} else {
    echo '<script>window.location.href = "/dashboard.php";</script>';
    echo '<noscript><meta http-equiv="refresh" content="0; url=/dashboard.php"></noscript>';
    exit;
}
?>

Этот вариант пытается сначала сделать серверный редирект, а если не получается — использует JavaScript, а для пользователей без JS — HTML-мета-редирект.

Важно: Всегда старайтесь использовать header() как основной метод, а клиентские — только как запасные. Серверный редирект быстрее, безопаснее и лучше индексируется поисковиками.