Как проверить, запущена ли уже сессия PHP, и избежать ошибки «headers already sent»
Проверка состояния сессии с помощью session_status()
Начиная с PHP 5.4.0 существует встроенная функция session_status(), которая возвращает текущее состояние сессии. Это наиболее правильный и современный способ проверить, запущена ли уже сессия.
Функция возвращает одну из трёх констант:
PHP_SESSION_DISABLED— сессии полностью отключены в конфигурации PHP.PHP_SESSION_NONE— сессии включены, но ни одна сессия ещё не запущена.PHP_SESSION_ACTIVE— сессия уже активна.
Таким образом, вы можете безопасно вызывать session_start() только если сессия ещё не запущена:
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
?>
Этот код проверяет, что сессии включены и не активны, и только тогда запускает новую сессию. Если сессия уже запущена, ничего не происходит — никаких ошибок.
Полный пример с include
В вашем случае лучше всего обернуть вызов session_start() в проверку в каждом файле, который может быть подключён. Так вы избежите дублирования:
<?php
// session_helper.php
function ensure_session_started() {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
}
?>
// config.php
require_once 'session_helper.php';
ensure_session_started();
$_SESSION['user'] = 'admin';
// page.php
require_once 'session_helper.php';
require_once 'config.php'; // config.php тоже вызывает ensure_session_started()
ensure_session_started(); // Второй вызов безопасен — сессия уже активна
?>
Старый способ (до PHP 5.4)
Если вы работаете с устаревшей версией PHP (что не рекомендуется), можно проверять через session_id():
<?php
if (session_id() === '') {
session_start();
}
?>
session_id() возвращает пустую строку, если сессия ещё не начата. Однако этот метод менее надёжен, так как session_id() может вернуть пустую строку и в случае, если сессии отключены. Поэтому предпочтительнее использовать session_status().
Важные замечания
- Всегда вызывайте
session_start()до любого вывода в браузер (включая пробелы, HTML-теги, echo). Иначе получите ошибку "headers already sent". - Используйте
require_onceвместоincludeилиrequireдля конфигурационных файлов с сессиями — это гарантирует, что файл будет подключён только один раз. - Рассмотрите использование единой точки входа (например,
index.php), где сессия запускается один раз, а все остальные скрипты подключаются уже после.
Таким образом, лучший ответ на ваш вопрос — использовать session_status() === PHP_SESSION_NONE для безопасного и читаемого кода.
Альтернативный подход: единая точка входа
Вместо того чтобы проверять статус сессии в каждом файле, можно организовать архитектуру приложения так, чтобы session_start() вызывался только один раз — в самом начале выполнения скрипта. Это избавляет от необходимости повторных проверок.
Создайте файл bootstrap.php (или init.php), который подключается самым первым:
<?php
// bootstrap.php
session_start();
?>
Затем в каждом скрипте, который должен работать с сессией, подключайте этот файл только один раз через require_once:
<?php
// index.php
require_once 'bootstrap.php';
// Дальше можно подключать любые другие файлы
// session_start() уже вызван, ошибок не будет
?>
Этот подход особенно удобен для небольших проектов и при использовании MVC-фреймворков, где есть чёткая точка входа (например, public/index.php).
Если же вы всё-таки предпочитаете проверять статус, используйте session_status() — это стандартное и надёжное решение для современных версий PHP.