Тайм-ауты сессий в PHP: лучшие практики - PullRequest
34 голосов
/ 06 августа 2009

Какая разница между session.gc_maxlifetime и session_cache_expire()?

Предположим, я хочу, чтобы сеанс пользователя был недействительным после 15 минут бездействия (а не через 15 после его первого открытия). Какой из них мне там поможет?

Я также знаю, что могу сделать session_set_cookie_params(), который может установить срок действия файла cookie пользователя через некоторое время. Однако срок действия файла cookie и срок действия сеанса на стороне сервера не совпадают; это также удаляет сеанс после истечения срока действия cookie?

Другое решение, которое у меня есть, простое $_SESSION['last_time'] = time() на каждый запрос и сравнивая сеанс с текущим временем, удаляя сессию на основе этого. Я надеялся, что для этого есть более «встроенный» механизм.

Спасибо.

Ответы [ 4 ]

54 голосов
/ 01 октября 2009

Я потратил некоторое время на поиски хорошего ответа на то, как работают настройки сервера php.ini. сеансы истекают. Я нашел много информации, но потребовалось время, чтобы понять, почему настройки работают так, как они. Если вы похожи на меня, это может быть полезно для вас:

Сеансы хранятся в виде файлов cookie (файлы на компьютере клиента) или на стороне сервера в виде файлов. на сервере. Оба метода имеют свои преимущества и недостатки.

Для сеансов, хранящихся на сервере, используются три переменные.

session.gc_probability session.gc_divisor session.gc_maxlifetime

(session.gc_probability / session.gc_divisor) создает вероятность того, что будет запущена программа сбора мусора. Когда работает сборщик мусора, он проверяет файлы сеансов, которые не были доступны по крайней мере для session.gc_maxlifetime и удаляет их.

Это все довольно хорошо объясняется в сообщениях на форуме (особенно это!) - Но возникают следующие вопросы:

1.) Как применяется эта вероятность? Когда сервер бросает кости?

A: Сервер бросает кости каждый раз, когда session_start () вызывается во время любой активный сеанс на сервере. Так что это означает, что вы должны увидеть мусор сборщик запускается примерно один раз за каждые 100 раз, когда вызывается session_start () если у вас есть значение по умолчанию session.gc_probability = 1 и session.gc_divisor = 100

2.) Что происходит на серверах с низким уровнем громкости?

A: Когда session_start () вызывается, FIRST обновляет сеанс и делает значения сеанса доступны для вас. Это обновляет время в вашем файле сеанса на сервер. Затем он бросает кости и, если он выигрывает (1 из 100 шансов), вызывает коллектор мусора. Затем сборщик мусора проверяет все файлы идентификаторов сеансов и проверяет, есть ли любой, имеющий право на удаление.

Так что это означает, что если вы единственный человек на сервере, ваш сеанс будет никогда не выключаться, и это будет выглядеть, как будто изменение настроек не имеет эффект. Допустим, вы измените session.gc_maxlifetime на 10 и session.gc_probability до 100. Это означает, что есть 100% шанс, что сборщик мусора запустится и удалит все файлы сессий, которые не были доступны в течение последних 10 секунд.

Если вы единственный на сервере, ваша сессия не будет удалена. Тебе нужно по крайней мере, 1 другой активный сеанс запущен, чтобы ваш стал неактивным.

Так что, в основном, на маломощном сервере или во время малой громкости - это может быть МНОГО дольше, чем session.gc_maxlifetime, прежде чем сборщик мусора будет работать и сеансы фактически удаляются. И не зная, как это работает, это может кажутся вам совершенно случайными.

3.) Почему они используют вероятность?

A: Производительность. На сервере с большим объемом вам не нужен сборщик мусора работает на каждый запрос session_start (). Это замедлит работу сервера без необходимости. Таким образом, в зависимости от объема вашего сервера, вы можете увеличить или уменьшите вероятность запуска сборщика мусора.

Я надеюсь, что это связывает вещи для вас. Если вы похожи на меня, и вы пытались session.gc_maxlifetime, и это не сработало (потому что вы пробовали на сервере разработки, чтобы никого не беспокоить), тогда этот пост надеюсь, избавил вас от царапин на голове.

Удачи!

40 голосов
/ 06 августа 2009

Каждый раз, когда session_start вызывается, метка времени файлов сеанса (если она существует) обновляется, которая используется для расчета, если session.gc_maxlifetime был превышен.

Что еще более важно, вы не можете зависеть от истечения сеанса после того, как session.gc_maxlifetime был превышен.

PHP запускает сборку мусора в сеансах с истекшим сроком действия после загрузки текущего сеанса и, используя session.gc_probability и session.gc_divisor , рассчитывает вероятность запуска сборки мусора. По умолчанию вероятность составляет 1%.

Если у вас небольшое количество посетителей, существует вероятность, что неактивный пользователь может получить доступ к сеансу, который должен был истечь и был удален. Если это важно для вас, вам нужно будет сохранить метку времени в сеансе и вычислить, как журнал неактивен.

Этот пример заменяет session_start и устанавливает таймаут:

function my_session_start($timeout = 1440) {
    ini_set('session.gc_maxlifetime', $timeout);
    session_start();

    if (isset($_SESSION['timeout_idle']) && $_SESSION['timeout_idle'] < time()) {
        session_destroy();
        session_start();
        session_regenerate_id();
        $_SESSION = array();
    }

    $_SESSION['timeout_idle'] = time() + $timeout;
}
5 голосов
/ 06 августа 2009

session.gc_maxlifetime основан на последнем изменении файла сеанса. Таким образом, каждый раз, когда файл сеанса изменяется или вызывается session_start () на отдельной странице, отсчет времени до gc_maxlifetime начинается заново, и пользователь остается «авторизованным». Это значение, которое вы ищете. Вы можете изменить это с помощью ini_set () в ваших файлах php или отредактировать php.ini, если у вас есть к нему доступ

session_cache_expire () контролирует только HTTP-заголовок «Expires». Этот заголовок определяет, как долго содержимое загруженной страницы остается в кэше браузера пользователя.

1 голос
/ 16 июля 2014

Чтобы проверить текущие значения, этот код будет полезен:

$gc_maxlifetime = ini_get('session.gc_maxlifetime');
$gc_probability = ini_get('session.gc_probability');
$gc_divisor     = ini_get('session.gc_divisor');
...