PHP session_start(): данные сеанса исчезают при обновлении страницы

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Здесь речь не об ошибке Permission denied при записи сеанса, а о ситуации, когда вызов session_start() проходит, но следующий HTTP-запрос получает новый сеанс или не читает данные из прежнего.

В этой статье
  1. Симптомы, область применения и причины
  2. Безопасная диагностика и пошаговое исправление
  3. Как проверить результат и что делать дальше

#Симптомы, область применения и причины

После успешного session_start() приложение снова просит войти или не видит значение $_SESSION. По шагам проверяем идентификатор cookie, домен, HTTPS, разные серверы и хранилище сеансов. Здесь речь не об ошибке Permission denied при записи сеанса, а о ситуации, когда вызов session_start() проходит, но следующий HTTP-запрос получает новый сеанс или не читает данные из прежнего.

Возможная причинаКак узнатьЧто делать
Браузер не возвращает cookie идентификатораCookie ограничен другим доменом, путём, Secure или SameSite.В ответе есть Set-Cookie, а в следующем запросе отсутствует Cookie с идентификатором сеанса.Сопоставить параметры cookie с фактическим HTTPS-адресом сайта.
Разные серверы используют разные хранилищаБалансировщик направляет запросы в разные PHP-FPM-узлы с локальным session.save_path.При обновлении значение $_SESSION появляется через раз; зависит от backend-узла.Использовать общее корректно настроенное серверное хранилище либо закрепить маршрутизацию временно для диагностики.
Сеанс уничтожается или сохраняется не тудаКод вызывает session_regenerate_id, session_destroy либо использует короткий gc_maxlifetime или разный session.save_handler.Cookie приходит стабильно, но данные пропадают сразу или через короткое время.Проверить путь выполнения, таймауты и место хранения без удаления всех сеансов.

#Безопасная диагностика и пошаговое исправление

  1. Подтвердите, что пропадает именно сеансОткройте сайт в отдельном профиле браузера и выполните одно простое действие, которое записывает значение в сессию (например, вход в тестовую учётную запись). Обновите страницу один раз; запишите время, адрес, случился ли выход и присутствует ли перенаправление с HTTP на HTTPS или между доменами. Если исчезает только оформление, а авторизация остаётся, проблема может быть в другом хранилище, а не в session_start().
  1. Посмотрите cookie на двух последовательных запросахВ Chrome/Firefox нажмите F12 → «Сеть», включите сохранение журнала, обновите страницу и выберите первый запрос. В «Заголовках» посмотрите Set-Cookie; затем выберите следующий запрос того же домена и найдите заголовок Cookie. Имя PHP-сеанса по умолчанию PHPSESSID, но приложение может установить иное. Не копируйте значение cookie, оно может предоставлять доступ к аккаунту. Если cookie не возвращается, проверьте Domain, Path, Secure и срок действия.
  1. Проверьте HTTPS, домен и путиСравните реальный адрес сайта с параметрами session.cookie_domain, session.cookie_path, session.cookie_secure, session.cookie_samesite. Для HTTPS cookie с Secure корректна, но на HTTP браузер её не отправит. Если приложение переносит пользователя с www.example.test на другой поддомен, cookie без подходящего Domain не перейдёт туда. Не отключайте Secure для рабочего сайта: исправьте схему HTTPS или согласуйте домен с архитектором. Убедитесь, что приложение не перенаправляет пользователя между разными хостами.
  1. Снимите безопасные диагностические показатели в веб-запросеРазработчик может на время записать в закрытый журнал значения session_status(), session_name(), ini_get("session.save_handler") и ini_get("session.save_path"). Сам session_id() и данные сеанса нельзя записывать целиком в доступный журнал; для сопоставления запросов используйте безопасный случайный идентификатор тестового действия, не связанный с действительным сеансовым cookie. Проверьте, что session_start() вызывается до вывода HTML.
  2. Пример кода по теме
    PHP
    Тестовые сообщения не содержат cookie и пользовательских данных; удалите диагностический код после проверки.
    <?php
    // Только закрытая тестовая страница; не выводите ID сеанса.
    $ok = session_start();
    error_log('session started: '.($ok ? 'yes' : 'no'));
    error_log('handler: '.ini_get('session.save_handler'));
    error_log('storage configured: '.(ini_get('session.save_path') !== '' ? 'yes' : 'default'));
  1. Проверьте фактическое хранилище и срок жизниВ панели параметров PHP домена найдите session.save_handler, session.save_path, session.gc_maxlifetime; у Redis/Memcached параметры задаются иначе и требуют соответствующего клиентского расширения. Если используется files, владелец процесса PHP-FPM должен иметь право записи в каталог. Но не выдавайте всему каталогу права 777. При проверке диска смотрите свободное место, права и ошибки журналов. Не удаляйте содержимое каталога сеансов: это немедленно разлогинит пользователей.
  1. Сравните соседние серверы и обработчики PHPЕсли перед сайтом есть балансировщик, попросите администратора посмотреть, на какой backend пришли два запроса. Проверьте, что у серверов одинаковые session.save_handler и логика приложений, а хранилище общее или предусмотрена устойчивость сеансов к распределению нагрузки. Если на одном сервере используется Redis, а на другом локальные файлы, данные будут исчезать. Не переключайте маршрутизацию рабочего кластера без плана отката.
  1. Найдите в коде явное уничтожение или смену идентификатораВ редакторе проекта выполните поиск по session_destroy, session_unset, session_regenerate_id и по местам, где присваивается $_SESSION = []. Смена идентификатора после входа сама по себе правильна для безопасности, поэтому не удаляйте session_regenerate_id только ради теста; проверьте правильность переноса состояния и времени вызова. Если данные теряются через заданное время, сопоставьте его с политикой истечения приложения и сервера.
  1. Проверьте два запроса и сохраните возможность возвратаПосле точечного исправления cookie, пути или общего хранилища войдите в тестовый аккаунт, перейдите на вторую страницу и обновите её несколько раз, а затем проверьте работу после обычного срока паузы. Если тест не прошёл, верните прежние параметры PHP/балансировщика из копии; приложите к заявке только времена запросов и описания заголовков, без значения идентификатора сессии.

#Как проверить результат и что делать дальше

Успех — после двух последовательных запросов и обычной паузы авторизация и контрольное значение $_SESSION сохраняются, а браузер отправляет согласованный cookie. Если значение исчезает только на части узлов, нужна проверка общего хранилища и маршрутизации администратором.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.