Подтвердить что ты не робот

Тайм-ауты сеанса в PHP: лучшие практики

Какова фактическая разница между session.gc_maxlifetime и session_cache_expire()?

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

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

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

Спасибо.

4b9b3361

Ответ 1

Каждый раз, когда session_start называется временной меткой файла сеанса (если она существует), обновляется, которая используется для вычисления if 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;
}

Ответ 2

Я потратил некоторое время на поиск хорошего ответа на то, как настройки сервера 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, он обновляет сеанс и делает доступных для вас. Это обновляет время вашего файла сеанса на сервер. Он THEN закатывает кости, и если он победит (1 из 100 шансов), он вызывает сборщик мусора. Затем сборщик мусора проверяет все файлы идентификаторов сеансов и видит, есть ли любые, которые могут быть удалены.

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

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

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

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

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

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

Удачи!

Ответ 3

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

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

Ответ 4

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

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