Как узнать, активен ли сеанс? - PullRequest
       1

Как узнать, активен ли сеанс?

41 голосов
/ 24 сентября 2010

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

$isSessionActive = (session_id() != "");

Или:

$isSessionActive = defined('SID');

Однако,оба они потерпят неудачу, если вы начнете сеанс, а затем закроете его;session_id() вернет идентификатор предыдущей сессии, а SID будет определено.Аналогичным образом, вызов session_start() в этот момент сгенерирует E_NOTICE, если у вас уже есть активный сеанс.Есть ли вменяемый способ проверить, активен ли в данный момент сеанс, не прибегая к буферизации вывода, оператору отключения (@session_start()) или чему-то еще, столь же хакерскому?

EDITЯ написал патч, чтобы попытаться включить эту функциональность в PHP: http://bugs.php.net/bug.php?id=52982

РЕДАКТИРОВАТЬ 29.08.2011: Новая функция добавлена ​​в PHP 5.4 для исправления этого: "Expose sessionстатус через новую функцию, session_status "

// as of 8/29/2011
$isSessionActive = (session_status() == PHP_SESSION_ACTIVE);

РЕДАКТИРОВАНИЕ 12/5/11: session_status () в руководстве по PHP.

Ответы [ 7 ]

22 голосов
/ 30 августа 2011

См. Изменения к исходному вопросу; в основном, PHP 5.4 и выше теперь имеет функцию session_status() для решения этой проблемы!

«Предоставить статус сеанса с помощью новой функции, session_status» (SVN Revision 315745)

Если вам нужна эта функциональность в версии, предшествующей PHP 5.4, см. ответ Хакре .

15 голосов
/ 24 сентября 2010

Я работал над этим, добавив несколько функций-оболочек вокруг различных функций создания / закрытия / уничтожения сеансов.В основном:

function open_session() {
     session_start();
     $_SESSION['is_open'] = TRUE;
}

function close_session() {
   session_write_close();
   $_SESSION['is_open'] = FALSE;
}

function destroy_session() {
   session_destroy();
   $_SESSION['is_open'] = FALSE;
}

function session_is_open() {
   return($_SESSION['is_open']);
}

Взломать, но выполнил то, что мне было нужно.

10 голосов
/ 05 октября 2011

Я тоже сталкиваюсь с этим, и настройка в $_SESSION не подходит для меня.Для PHP 5.3.8:

  1. Если с запросом был запущен какой-либо сеанс, define('SID') вернет FALSE, а $_SESSION не установлено.
  2. Этоне зависит, был ли session_id() использован для установки идентификатора сеанса или нет.
  3. После первого session_start(), SID определено и $_SESSION установлено в пустой массив.
  4. session_destroy() сбрасывает session_id(), тогда это пустая строка.SID останется определенным (и будет установлено его предыдущее значение, которое может быть пустой строкой).$_SESSION оставлено без изменений.Он будет сброшен / заполнен в следующий раз при вызове session_start.

С этими состояниями, тем более что между ними можно вызвать session_id(), чтобы установить идентификатор для next сеанс, невозможно безопасно определить состояние сеанса с помощью SID, $_SESSION и session_id().

«Попытка» с помощью session_start() (например, с @) может быть не очень полезной,так как это изменит статус сеанса и изменит содержимое $_SESSION (и добавит заголовок set-cookie, если cookie не был частью запроса).В моем случае это не подходило.

Пока я выполнял тесты, я столкнулся с тем, что нельзя пытаться изменить настройку ini session.serialize_handler, когда сеанс активен, даже когда выустановите его на то же значение.То же самое верно для session.use_trans_sid Документов , что является более легким.Это привело меня к следующей функции:

/**
 * @return bool
 */
function session_is_active()
{
    $setting = 'session.use_trans_sid';
    $current = ini_get($setting);
    if (FALSE === $current)
    {
        throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting));
    }
    $result = @ini_set($setting, $current); 
    return $result !== $current;
}

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

Чтобы эта функция была совместима с PHP 5.2, требуется небольшая модификация:

/**
 * @return bool
 */
function session_is_active()
{
    $setting = 'session.use_trans_sid';
    $current = ini_get($setting);
    if (FALSE === $current)
    {
        throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting));
    }
    $testate = "mix$current$current";
    $old = @ini_set($setting, $testate);
    $peek = @ini_set($setting, $current);
    $result = $peek === $current || $peek === FALSE;
    return $result;
}

Некоторые песочница .

5 голосов
/ 24 сентября 2010

Следующий код выдает мне только один session_id (), а не два

session_start();
echo session_id();
session_destroy();
echo session_id();

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

session_start();
$_SESSION['intialized'] = 'This will not print';
$_SESSION = array(); // Unset all variables
session_destroy();
echo $_SESSION['initialized']; // No output
1 голос
/ 06 февраля 2013

Вот хорошая замена, которая не сломает вещи при переходе на 5.4:

if(!function_exists('session_status')){
    function session_active(){
        return defined('SID');   
    }
}else{
    function session_active(){
        return (session_status() == PHP_SESSION_ACTIVE);   
    }        
}
0 голосов
/ 07 мая 2013

Существует несколько мест, которые необходимо проверить, чтобы убедиться, что сеанс активен:

1 - файл cookie существует и его срок действия не истек. 2 - базовый механизм хранения сеанса (файловая система или база данных) имеет запись, соответствующую файлу cookie.

0 голосов
/ 24 сентября 2010

Кен, если сеанс уничтожен, массив $ _SESSION не должен быть доступен ... или, по крайней мере, ваши значения должны быть не установлены. Итак, теоретически (не проверено) вы должны иметь возможность проверить массив на предмет значения, чтобы узнать, установлено ли что-либо в данный момент.

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