По запросу существует несколько разных способов, которыми вы можете определить, был ли запущен сеанс, например:
$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
EDIT 8/29/2011: новая функция добавлена в PHP 5.4, чтобы исправить это: «Открыть статус сеанса с помощью новой функции, session_status»
// as of 8/29/2011 $isSessionActive = (session_status() == PHP_SESSION_ACTIVE);
EDIT 12/5/11: session_status () в руководстве по PHP.
См. Редактирование исходного вопроса; в основном, PHP 5.4 и выше теперь имеет функцию session_status()
для решения этой проблемы!
«Открыть статус сеанса с помощью новой функции, session_status» (SVN Revision 315745)
Если вам нужна эта функциональность в версии до версии PHP 5.4, см . Ответ hakre .
Я работал над этим, добавив пару функций оболочки вокруг различных функций создания сеанса / закрытия / уничтожения. В основном:
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']); }
Хакки, но сделал то, что мне нужно.
Я тоже сталкиваюсь с этим, и настройка в $_SESSION
для меня не является вариантом. Для PHP 5.3.8:
define('SID')
вернет FALSE
, а также $_SESSION
будет установлен. session_id()
для установки идентификатора сеанса или нет. session_start()
определяется SID
а $_SESSION
– пустой массив. session_destroy()
отключает session_id()
, тогда это пустая строка. SID
будет оставаться определенным (и установить его прежнее значение, которое может быть пустой строкой). $_SESSION
остается неизменным. Он будет сбрасываться / заполняться в следующий раз, когда вызывается session_start
. С этими состояниями, особенно в том случае, когда session_id()
можно вызвать между ними, чтобы установить идентификатор для следующего сеанса, невозможно безопасно определить состояние сеанса с SID
, $_SESSION
и session_id()
.
«Попытка» с session_start()
(например, с @
) может оказаться не очень полезной, так как это изменит статус сеанса и изменит содержимое $_SESSION
(и добавит заголовок set-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; }
Некоторые песочницы .
Следующий код только сбрасывает один 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
Вот хорошее падение в замене, которое не сломается, когда вы перейдете к 5.4:
if(!function_exists('session_status')){ function session_active(){ return defined('SID'); } }else{ function session_active(){ return (session_status() == PHP_SESSION_ACTIVE); } }
Кен, если сеанс уничтожен, массив $ _SESSION не должен быть доступен … или, по крайней мере, ваши значения должны быть отменены. Итак, в теории (untested) вы должны иметь возможность проверить массив на значение, чтобы знать, установлено ли что-либо в данный момент.
Для проверки активности сеанса необходимо проверить несколько мест:
1-файл cookie существует и не истечет. 2-й механизм хранения основной сессии (файловая система или база данных) имеет запись, соответствующую файлу cookie.