Перезапустить сеанс по истечении времени ожидания в PHP

Я пытаюсь перезапустить сеанс с истекшим сроком действия после перезагрузки страницы. Вот минимальный пример кода:

<?php

$timeout = 3;
ini_set('session.gc_maxlifetime', $timeout);
session_name('mytest');
session_start();

if (isset($_SESSION['LAST_ACTIVE']) && (time() - $_SESSION['LAST_ACTIVE'] > $timeout))
{
    foreach ($_COOKIE as $k => $v)
        setcookie($k, $v, time() - 3600, '/');

    echo 'session cookie destroyed<br />';

    session_destroy();
    session_start();
}

$_SESSION['LAST_ACTIVE'] = time();

?>

<a href = "<?=$_SERVER['PHP_SELF']?>">Reload</a>

Что здесь происходит, так это то, что нажатие на ссылку Reload через 3 секунды разрушает сеанс (здесь нет проблем). Но поскольку я снова запустил session_start() после session_destroy();, я ожидаю, что он снова создаст новый сеанс, но этого не происходит. Мне нужно дважды нажать «Обновить», чтобы сеанс возобновился.

Есть ли способ перезапустить сеанс при загрузке одной страницы?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
0
181
1

Ответы 1

Пока не уверен на 100% в этом. Подозреваю, причина в setcookie.

Вот более подробное объяснение:

session_destroy() destroys all of the data associated with the current session. It does not unset any of the global variables associated with the session, or unset the session cookie. To use the session variables again, session_start() has to be called.

Теперь вот в чем проблема:

Файлы cookie хранятся в браузере пользователя и могут быть установлены или уничтожены только в браузере. setcookie - это, по сути, удобная функция, которая устанавливает соответствующие заголовки для установки / отключения файлов cookie и, следовательно, не оказывает фактического влияния на файлы cookie пользователя, пока не будет отправлен ответ.

Вот что, как я предполагаю, произошло:

  1. session_destroy удалил все данные сеанса, но сохранил файл cookie сеанса.
  2. session_start повторно использовал тот же файл cookie, но теперь без каких-либо данных сеанса.
  3. Ответ был отправлен клиенту, который затем удалил файл cookie сеанса.
  4. Это означает, что любые данные, добавленные после комбо session_destroy/session_start, были потеряны.

Вот пара вещей, которые могут сработать.

  1. Сгенерируйте новый идентификатор сеанса, когда вы уничтожите сеанс. Надеюсь, это создаст новый файл cookie сеанса:

    session_regenerate_id(true);
    
  2. Отразите запланированные изменения файлов cookie перед фактическим перезапуском сеанса:

    session_destroy();
    foreach ($_COOKIE as $k => $v) {      
        setcookie($k, $v, time() - 3600, '/');
        unset($_COOKIE[$k]);
    }
    session_start();
    

Если ничего не работает, вам может потребоваться немедленное перенаправление на страницу, которая правильно запустит сеанс, а затем перенаправление на последнюю страницу, на которую вам нужно перейти:

foreach ($_COOKIE as $k => $v)
    setcookie($k, $v, time() - 3600, '/');

session_destroy(); 
header("Location: /restartSession");

Опять же, я хочу указать, что я просто размышляю, возможно, вы сможете получить более твердый ответ от того, кто лучше знает внутреннюю работу сеанса PHP.

Спасибо за подробности, но ничего из этого не работает. Даже header('location: ...') не работал. Однако ручное обновление с задержкой в ​​1 секунду работает. Например, header('refresh:1; url='.$_SERVER['PHP_SELF']);, но это вполне ожидаемо, поскольку по сути это двойная перезагрузка.

IMB 25.07.2018 18:42

@apokryfos Это действительно глубокий анализ, и я хотел бы добавить, что использование ajax для установки правильных файлов cookie также может быть возможным решением, поскольку нет принципиальной разницы между обычным запросом и запросом ajax в отношении файлов cookie.

Vinay 25.07.2018 19:06

Другие вопросы по теме