Проверьте, началась ли сессия PHP

461

У меня есть файл PHP, который иногда вызывается со страницы, с которой начался сеанс, а иногда со страницы, с которой не начался сеанс. Поэтому, когда у меня есть session_start()этот скрипт, я иногда получаю сообщение об ошибке «сессия уже началась». Для этого я поставил эти строки:

if(!isset($_COOKIE["PHPSESSID"]))
{
  session_start();
}

но на этот раз я получил это предупреждение:

Примечание: неопределенная переменная: _SESSION

Есть ли лучший способ проверить, началась ли сессия уже?

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

логан
источник
2
Возможный дубликат, как я могу проверить, был ли введен session_start?
Ричард Харрисон
См. Также ответы Stackoverflow: stackoverflow.com/questions/1545357/…
contact-form.co_you_go

Ответы:

761

Рекомендуемый способ для версий PHP> = 5.4.0, PHP 7

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

Ссылка: http://www.php.net/manual/en/function.session-status.php

Для версий PHP <5.4.0

if(session_id() == '') {
    session_start();
}
lovelyramos
источник
1
Я думаю, что есть проблема с решением для PHP <5.4. Параметр session_id устанавливается при первом запуске сеанса, но не удаляется при закрытии сеанса. Так, например, если перед вашим фрагментом есть код вроде session_start();session_write_close();: тогда условие if не выполняется, но у нас нет открытого сеанса ...
Nicolò Martini
@Nicolo Martini Насколько я понимаю: сессия, начинающаяся session_start()в верхней части скрипта, ЗАКРЫВАЕТСЯ при выходе из скрипта, ИЛИ когда session_write_closed()вызывается до его завершения. Т.е. сеанс ЗАКРЫВАЕТСЯ, когда его данные записываются в файл cookie сеанса, и сеанс разблокируется для доступа другим скриптом, который также вызывает 'session_start'. ЗАКРЫТИЕ НЕ означает, что сеанс УНИЧТОЖЕН, поэтому. Вы можете закрыть сеанс, выйдя из текущего скрипта или вызова session_write_close(), и вы можете открыть его снова, вызвав session_start(). Мое понимание, по крайней мере.
Стефан
1
Это все еще хороший способ начать сеанс? Потому что в ссылке нет ничего связанного с этим ответом
csandreas1
@ csandreas1 вы увидите по ссылке описание session_status и его ожидаемые возвращаемые значения. Ответ на ваш вопрос - да!
lovelyramos
У меня был этот сбой в некоторых обстоятельствах - я использовал if (! Isset ($ _ SESSION)) с успехом
Скотт
161

Для версий PHP до PHP 5.4.0:

if(session_id() == '') {
    // session isn't started
}

Хотя, IMHO, вам стоит подумать о рефакторинге кода управления сеансом, если вы не знаете, запущен сеанс или нет ...

Тем не менее, мое мнение субъективно, и есть ситуации (примеры которых описаны в комментариях ниже), где может быть невозможно узнать, начался ли сеанс.

Alex
источник
37
Не обязательно плохо знать, начался ли ваш сеанс. Если вы лениво загружаете (только начинаете сессию, когда это необходимо), тогда тест в вашем ответе будет в порядке.
Дрюм
1
Также в некоторых средах apache настроил автозапуск сеанса
LeonardChallis
Пример для тестирования, если session_id () возвращает пустую строку во включаемом файле:
tgoneil
3
Комментарий о рефакторинге управления сеансом, если вы не знаете, был ли он отфильтрован или нет, не очень актуален. Например, если кодировать расширенные функции в тему WordPress, вы никогда не узнаете, начал ли плагин использовать сеансы без проверки. Мир кодирования не всегда такой черно-белый: P
Джимбо Джонни
Ммм, хорошие моменты действительно. Я признаю, что мои комментарии очень субъективны - я исправлю свой ответ, чтобы отразить это.
Алекс
71

В PHP 5.4 введен метод session_status () , который более надежен, чем полагается session_id().

Рассмотрим следующий фрагмент:

session_id('test');
var_export(session_id() != ''); // true, but session is still not started!
var_export(session_status() == PHP_SESSION_ACTIVE); // false

Итак, чтобы проверить, запущен ли сеанс, рекомендуемый путь в PHP 5.4:

session_status() == PHP_SESSION_ACTIVE
Вениамин
источник
3
Фрагмент кода, который использует session_status, когда он доступен, и более старые методы, когда он не кажется идеальным, кстати, подсказка :)
Джимбо Джонни
1
Спасибо за обновление, Бенджамин. Хорошо знать, что с PHP 5.4 можно использовать новый метод.
Логан
1
Это гораздо лучший способ проверить это, вы не всегда знаете, если у вас начался сеанс, особенно когда пользователь очищает куки, когда он находится в середине просмотра сайта ... Я всегда пишу код для двухлетнего, вы никогда не знаю, что собираются делать пользователи ;-) Что касается меня, у меня есть небольшой файл Config.php, который вызывается во всех моих сценариях для настройки переменных и другой информации, поэтому простое добавление этого в этот файл всегда гарантирует, что сеанс запускается, если это необходимо
Энди Брахам
35

Вы можете сделать это, и это действительно легко.

if (!isset($_SESSION)) session_start();

Надеюсь, поможет :)

miyuru
источник
6
@zloctb: я не могу придумать ни одной ситуации, в которой бы я поступил $_SESSION=array();, поэтому этот ответ кажется нормальным.
Оффер
5
@halfer Смотрите ответ Райана. Если session_destroy()был вызван, то $_SESSIONвсе еще может быть установлен. Кроме того, в модульных тестах вы можете установить $_SESSIONнапрямую. Но я высказался против этого, так как для большинства практических ситуаций этот ответ должен быть достаточно хорошим (до тех пор, пока PHP 5.3 больше никогда не увидится ...)
Даррен Кук
22
if (version_compare(phpversion(), '5.4.0', '<')) {
     if(session_id() == '') {
        session_start();
     }
 }
 else
 {
    if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }
 }
k.bon
источник
21

До PHP 5.4 не было надежного способа узнать, кроме установки глобального флага.

Рассматривать:

var_dump($_SESSION); // null
session_start();
var_dump($_SESSION); // array
session_destroy();
var_dump($_SESSION); // array, but session isn't active.

Или:

session_id(); // returns empty string
session_start();
session_id(); // returns session hash
session_destroy();
session_id(); // returns empty string, ok, but then
session_id('foo'); // tell php the session id to use
session_id(); // returns 'foo', but no session is active.

Итак, до PHP 5.4 вы должны установить глобальное логическое значение.

RY
источник
12

Для всех версий PHP

if ((function_exists('session_status') 
  && session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
  session_start();
}
supersuphot
источник
1
Точно так же можно было бы сделатьif ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Энтони Хатзопулос
9

Проверь это :

<?php
/**
* @return bool
*/
function is_session_started()
{
    if ( php_sapi_name() !== 'cli' ) {
        if ( version_compare(phpversion(), '5.4.0', '>=') ) {
            return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
        } else {
            return session_id() === '' ? FALSE : TRUE;
        }
    }
    return FALSE;
}

// Example
if ( is_session_started() === FALSE ) session_start();
?>

Источник http://php.net

Эльшан
источник
6

Используйте session_id () , она возвращает пустую строку, если не установлена. Это надежнее, чем проверка $_COOKIE.

if (strlen(session_id()) < 1) {
    session_start();
}
Уэсли ван Опдорп
источник
5
if (session_id() === "") { session_start(); }

Надеюсь, поможет !

Махеш Челия
источник
5

Это должно работать для всех версий PHP. Он определяет версию PHP, а затем проверяет, запущен ли сеанс на основе версии PHP. Затем, если сеанс не запущен, он начинает его.

function start_session() {
  if(version_compare(phpversion(), "5.4.0") != -1){
    if (session_status() == PHP_SESSION_NONE) {
      session_start();
    }
  } else {
    if(session_id() == '') {
      session_start();
    }
  }
}
Дастин Пуассан
источник
4

Единственное, что вам нужно сделать, это:

<?php
if(!isset($_SESSION))
{
session_start();
}
?>
user3140580
источник
Это тот, который я использовал на протяжении многих лет. Кто-нибудь советует не использовать этот? Конечно, хорошо использовать проверку, если сеанс иногда запускается - в некоторых средах apache имеет настройку автозапуска сеанса, ленивую загрузку (только начало сеанса, когда это необходимо) или просто что иногда нужно просто сделать быстрый взлом
K Килиан Линдберг
ТО ЖЕ ОТВЕТ ВЫШЕ (@miyuru)
2

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

   /**
    * Start session
    * Fall back to ukrainian language
    */
   function valid_session() {
    if(session_id()=='') {
        session_start();
        $_SESSION['lang']='uk';
        $_SESSION['lang_id']=3;
    }
    return true;
  }
Алекс Химич
источник
2

@ перед вызовом функции подавляет любые ошибки, о которых можно сообщить во время вызова функции.

Добавление @before session_startзаставляет PHP избегать вывода сообщений об ошибках.

Например:

Использование session_start()после того, как вы уже что-то напечатали в браузере, приводит к ошибке, поэтому PHP отобразит что-то вроде «заголовки не могут быть отправлены: началось с (строка 12)», @session_start()в этом случае все равно не будет работать, но сообщение об ошибке не будет напечатано экран.

Перед включением файлов или перенаправлением на новую страницу используйте exit()функцию, иначе она выдаст ошибку.

Этот код можно использовать во всех случаях:


    <?php 
        if (session_status() !== PHP_SESSION_ACTIVE || session_id() === ""){
            session_start(); 
        }
    ?>
Sangram Desai
источник
1

На PHP 5.3 это работает для меня:

if(!strlen(session_id())){
    session_name('someSpecialName');
    session_start();
} 

тогда у вас есть. Если вы не поместите оператор not at if в начало, сеанс начнется любым способом, я не знаю почему.

Лукас М. Оливейра
источник
1

Ответ на основе @Meliza Ramos Response (см. Первый ответ) и http://php.net/manual/en/function.phpversion.php ,

ДЕЙСТВИЯ:

  • определить PHP_VERSION_ID, если не существует
  • определить функцию для проверки версии на основе PHP_VERSION_ID
  • определить функцию для openSession () безопасный

использовать только openSession ()

    // PHP_VERSION_ID is available as of PHP 5.2.7, if our
    // version is lower than that, then emulate it
    if (!defined('PHP_VERSION_ID')) {
        $version = explode('.', PHP_VERSION);

        define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));


        // PHP_VERSION_ID is defined as a number, where the higher the number
        // is, the newer a PHP version is used. It's defined as used in the above
        // expression:
        //
        // $version_id = $major_version * 10000 + $minor_version * 100 + $release_version;
        //
        // Now with PHP_VERSION_ID we can check for features this PHP version
        // may have, this doesn't require to use version_compare() everytime
        // you check if the current PHP version may not support a feature.
        //
        // For example, we may here define the PHP_VERSION_* constants thats
        // not available in versions prior to 5.2.7

        if (PHP_VERSION_ID < 50207) {
            define('PHP_MAJOR_VERSION',   $version[0]);
            define('PHP_MINOR_VERSION',   $version[1]);
            define('PHP_RELEASE_VERSION', $version[2]);

            // and so on, ...
        }
    }

    function phpVersionAtLeast($strVersion = '0.0.0')
    {
        $version = explode('.', $strVersion);

        $questionVer = $version[0] * 10000 + $version[1] * 100 + $version[2];

        if(PHP_VERSION_ID >= $questionVer)
            return true;
        else
            return false;

    }

    function openSession()
    {
        if(phpVersionAtLeast('5.4.0'))
        {
            if(session_status()==PHP_SESSION_NONE)
                session_start();
        }
        else // under 5.4.0
        {
            if(session_id() == '')
                session_start();
        }
    }

источник
1
if (version_compare(PHP_VERSION, "5.4.0") >= 0) {
    $sess = session_status();
    if ($sess == PHP_SESSION_NONE) {
        session_start();
    }
} else {
    if (!$_SESSION) {
        session_start();
    }
}

На самом деле, сейчас слишком поздно, чтобы объяснить это здесь, так как это было решено. Это был файл .inc одного из моих проектов, где вы настраивали меню для ресторана, выбирая блюдо и удаляя / добавляя или изменяя порядок. Сервер, на котором я работал, не имел реальной версии, поэтому я сделал его более гибким. Это зависит от авторов, которые хотят использовать и попробовать.

Thielicious
источник
1

Этот фрагмент кода работает для вас?

if (!count($_SESSION)>0) {
    session_start();
}
Niroshan
источник
0

Вы должны реорганизовать свой код так, чтобы вы вызывали его session_start()ровно один раз за исполнение страницы.

Samt
источник
4
в некоторых ситуациях вызывать его ровно один раз за выполнение страницы может быть нежелательно.
Тимо Хуовинен
Если вы убиваете сеанс, чтобы воссоздать его, тогда, конечно, но это особый случай. В общем, приложение должно иметь код, который запускается в самом начале один раз, и именно туда идет session_start ().
SamT
1
например, приложение сохраняет сеансы в файле и должно загрузить 2 одновременных медленных запроса данных, ни один из этих запросов не требует сеансов, но один будет блокировать другой, потому что session_start блокирует файл сеанса.
Тимо Хуовинен
Точно. @YuriKolovsky прав. Вопрос Алекса уместен, потому что такие случаи могут случиться, и они не редкость.
Пауло Коги - Восстановить Монику
14
-1, большинство веб-сайтов управляются CMS и имеют такие вещи, как темы и плагины, часто написанные разными сторонами, никогда не зная, начал ли код друг друга сеансы или нет. Подразумевается, что это только проблема организации кода, является ложной.
Джимбо Джонни
0
session_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}
Суканья Суку
источник
0

PHP_VERSION_ID доступен начиная с PHP 5.2.7, поэтому сначала проверьте это и, если необходимо, создайте его. session_statusдоступно с версии PHP 5.4, поэтому мы должны проверить это тоже:

if (!defined('PHP_VERSION_ID')) {
    $version = explode('.', PHP_VERSION);
    define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}else{
    $version = PHP_VERSION_ID;
}
if($version < 50400){
    if(session_id() == '') {
        session_start();
    }
}else{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }
}
Кристиан Крузе
источник
0

Исходя из моей практики, перед обращением к $_SESSION[]вам нужно session_startкаждый раз звонить, чтобы использовать скрипт. Смотрите ссылку ниже для руководства.

http://php.net/manual/en/function.session-start.php

Для меня, по крайней мере session_start, сбивает с толку, как имя. А session_loadможет быть более понятным.

Эдуард Хасанай
источник
0

я закончил с двойной проверкой статуса. PHP 5.4+

if(session_status() !== PHP_SESSION_ACTIVE){session_start();};
if(session_status() !== PHP_SESSION_ACTIVE){die('session start failed');};
Лео Тахк
источник
0

Вы можете использовать следующее решение, чтобы проверить, начался ли уже сеанс PHP:

if(session_id()== '')
{
   echo"Session isn't Start";
}
else
{
    echo"Session Started";
}
Манджит Кумар Най
источник
Действительный ответ более подробно.
Клеман Прево
0

Это то, что я использую, чтобы определить, начался ли сеанс. Используя empty и isset следующим образом:

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}
Rotimi
источник
-3

Заменить session_start();на:

if (!isset($a)) {
    a = False;
    if ($a == TRUE) {
        session_start();
        $a = TRUE;
    }
}
Харшит Чатурведи
источник
он содержит ошибки кода и будет работать только в том случае, если один и тот же файл будет включен несколько раз, но не при закрытии.
BananaAcid