PHP - ini_set ('session.gc_maxlifetime', 5) - Почему это не завершает сеанс? - PullRequest
18 голосов
/ 07 августа 2010

PHP-скрипт выглядит следующим образом:

<?php // continue.php
ini_set('session.gc_maxlifetime', 5);
session_start();
echo ini_get('session.gc_maxlifetime');
// wait for 7 seconds
usleep(7000000);
if (isset($_SESSION['username']))
{
    $username = $_SESSION['username'];
    $password = $_SESSION['password'];
    $forename = $_SESSION['forename'];
    $surname  = $_SESSION['surname'];

    echo "Welcome back $forename.<br />
          Your full name is $forename $surname.<br />
          Your username is '$username'
          and your password is '$password'.";
}
else echo "Please <a href=authenticate2.php>click here</a> to log in.";

?>

В зависимости от времени ожидания (т. Е. 5 секунд), скрипт не должен ничего распечатывать.Тем не менее, я все еще получаю следующее сообщение

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'.

Кажется, что строка ini_set ('session.gc_maxlifetime', 5) не работает, как должно быть.Я использую windowsXP + XAMMP.

Можете ли вы сказать мне, как заставить это работать?

Спасибо

Ответы [ 4 ]

36 голосов
/ 07 августа 2010

Даже если сборщик мусора включится и удалит файл сеанса, который вы открыли / прочитали с помощью session_start(), он НЕ попадет в кишки этого конкретного процесса PHP и не удалит массив объектов $_SESSION.

Предполагая, что вы работаете со стандартным файловым обработчиком сеанса (который содержит serialize() 'копию $_SESSION), вот что происходит.

  1. Файл сеанса находится в своем временном каталоге
  2. Вы session_start(), что заставляет PHP открывать / блокировать файл, читать его содержимое, десериализовывать данные и, между прочим, возможно обновлять метку времени последнего использования файла сеанса (atime на блоках Unix).
  3. Если звезды и луна правильно выровнены с асцендентом Нептуна в пятом доме, сборщик мусора сессии МОЖЕТ запустить и удалить старые файлы сессии.
  4. Сборщик мусора выполнит итерацию по каталогу сеанса и удалит все файлы, которые старше max_liftime, НО НЕ УДАЛИТ ЛЮБЫХ ФАЙЛОВ, В КОТОРЫХ В НАСТОЯЩЕЕ ВРЕМЯ ОТКРЫТО / В ИСПОЛЬЗОВАНИЕ . Поскольку вы не закрыли () сеанс, файл сеанса все еще используется, поэтому не будет удален.

Теперь, если вы сделали что-то вроде этого:

ini_set(...); // set GC probability to max, short session lifetime, etc...

session_start(); // populate $_SESSION
session_write_close(); // dump $_SESSION out to file, close file, release lock.

sleep(7); // Sleep for 7 seconds;

session_start(); // re-populate $_SESSION;

Теперь вы можете просто получить новый пустой $ _SESSION, IF , который решит запустить сборщик мусора. Однако, если вы не сделаете эту секунду session_start(), старые данные $ _SESSION из предыдущего start () вызов БУДЕТ ЕЩЕ НАСТОЯЩИМ . Возможно, файл сеанса был удален, но сборщик мусора не будет касаться того, что присутствует в памяти вашего скрипта, во время его работы.

9 голосов
/ 07 августа 2010

session.gc_maxlifetime - количество секунд, по истечении которых сеанс будет считаться для сборки мусора.

session.gc_probability и session.gc_divisor затем определяютвероятность того, что сборка мусора будет выполнена при любой инициализации сеанса

4 голосов
/ 07 августа 2010

Прочтите руководство (выделено мной):

session.gc_maxlifetime указывает количество секунд, по истечении которых данные будут считаться «мусором», а потенциально будет очищено. Сборка мусора может происходить во время запуска сеанса (в зависимости от session.gc_probability и session.gc_divisor).

На той же странице:

session.gc_divisor в сочетании с session.gc_probability определяет вероятность того, что процесс gc (сборка мусора) запускается при каждой инициализации сеанса. Вероятность рассчитывается с использованием gc_probability/gc_divisor, например, 1/100 означает, что есть вероятность 1%, что процесс GC запускается при каждом запросе. session.gc_divisor по умолчанию 100.

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

Вам следует сохранить в сеансе переменную, которая сохраняет время последней активности пользователя, и использовать ее вместо сеанса логически «активной». Не полагайтесь на сборку мусора.

1 голос
/ 07 августа 2010

Я не думаю, что именно так gc_maxlifetime должен работать. В руководстве написано

session.gc_maxlifetime указывает количество секунд, по истечении которых данные будут рассматриваться как «мусор» и потенциально будет очищено.

(акцент мой)

в вашем случае сеанс все еще активен. Поэтому я не думаю, что это будет предметом сборки мусора.

Вы можете попробовать сделать session_write_close() перед сном (). Это может увеличить вероятность того, что сборщик мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...