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

415

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

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

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

Примечание: переменная Undefined: _SESSION

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

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

Теги:
session
session-variables

26 ответов

629
Лучший ответ

Рекомендуемый способ для версий 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();
}
  • 1
    Я думаю, что есть проблема с решением для PHP <5.4. Параметр session_id устанавливается при первом запуске сеанса, но он не удаляется при закрытии сеанса. Так, например, если перед вашим фрагментом есть код, подобный session_start();session_write_close(); : тогда условие if не выполняется, но у нас нет открытого сеанса ...
  • 0
    @Nicolo Martini Насколько я понимаю: сессия, начавшаяся с session_start() в верхней части скрипта, закрывается при выходе из скрипта, ИЛИ при session_write_closed() перед выходом из скрипта. Т.е. сеанс ЗАКРЫВАЕТСЯ, когда его данные записываются в файл cookie сеанса, и сеанс разблокируется для доступа другим сценарием, который также вызывает 'session_start'. ЗАКРЫТИЕ НЕ означает, что сеанс УНИЧТОЖЕН, поэтому. Вы можете закрыть сеанс, выйдя из текущего скрипта или вызвав session_write_close() , и вы можете открыть его снова, вызвав session_start() . Мое понимание, по крайней мере.
Показать ещё 2 комментария
160

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

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

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

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

  • 36
    Не обязательно плохо знать, начался ли ваш сеанс. Если вы лениво загружаете (только начинаете сессию, когда это необходимо), тогда тест в вашем ответе будет в порядке.
  • 1
    Также в некоторых средах apache настроил автозапуск сеанса
Показать ещё 6 комментариев
72

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 комментарий
35

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

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

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

  • 6
    @zloctb: я не могу вспомнить ни одной ситуации, в которой я бы сделал $_SESSION=array(); так что этот ответ кажется нормальным.
  • 5
    @halfer Смотри ответ Райана. Если session_destroy() был вызван, тогда $_SESSION все еще может быть установлен. Кроме того, в модульных тестах вы можете установить $_SESSION напрямую. Но я проголосовал за это, так как для большинства практических ситуаций этот ответ должен быть достаточно хорошим (до тех пор, пока PHP 5.3 больше никогда не увидится ...)
22

До 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 вы должны установить глобальное логическое значение.

20
if (version_compare(phpversion(), '5.4.0', '<')) {
     if(session_id() == '') {
        session_start();
     }
 }
 else
 {
    if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }
 }
10

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

if ((function_exists('session_status') 
  && session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
  session_start();
}
  • 0
    Точно так же можно сделать, 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

Это должно работать для всех версий 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();
    }
  }
}
5
if (session_id() === "") { session_start(); }

надеюсь, что это поможет!

4

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

<?php
if(!isset($_SESSION))
{
session_start();
}
?>
  • 0
    Это тот, который я использовал на протяжении многих лет. Кто-нибудь советует не использовать этот? Конечно, хорошо использовать проверку, если сеанс иногда запускается - в некоторых средах apache имеет функцию автозапуска сеанса, ленивую загрузку (только начало сеанса, когда это необходимо) или просто то, что иногда нужно просто сделать быстрый взлом
  • 0
    ЭТО ЖЕ ОТВЕТ ВЫШЕ (@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;
  }
1

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

if (!count($_SESSION)>0) {
    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 одного из моих проектов, в котором вы настраиваете меню для ресторана, выбирая блюдо, удаляя/добавляя или изменяя заказ. На сервере, на котором я работал, не было реальной версии, поэтому я сделал ее более гибкой. Это авторы хотят использовать и попробовать.

1

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

Actions:

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

используйте 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 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

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

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

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

1

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

  • 3
    в некоторых ситуациях вызывать его ровно один раз за выполнение страницы может быть нежелательно.
  • 0
    Если вы убиваете сеанс, чтобы воссоздать его, тогда, конечно, но это особый случай. В общем, приложение должно иметь код, который запускается один раз в самом начале, и именно туда идет session_start ().
Показать ещё 3 комментария
0

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

if(session_id()== '')
{
   echo"Session isn't Start";
}
else
{
    echo"Session Started";
}
  • 0
    Действительный ответ более подробно.
0

Я закончил с двойной проверкой статуса. php 5. 4+

if(session_status() !== PHP_SESSION_ACTIVE){session_start();};
if(session_status() !== PHP_SESSION_ACTIVE){die('session start failed');};
0

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

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

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

0

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

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}
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_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}
-1

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

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

Например:

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

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

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


    <?php 
        if (session_status() !== PHP_SESSION_ACTIVE || session_id() === ""){
            session_start(); 
        }
    ?>

-3

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню