Sprawdź, czy sesja PHP już się rozpoczęła


461

Mam plik PHP, który jest czasami wywoływany ze strony, która rozpoczęła sesję, a czasami ze strony, która nie rozpoczęła sesji. Dlatego gdy mam session_start()ten skrypt, czasami pojawia się komunikat o błędzie „sesja już się rozpoczęła”. W tym celu umieściłem następujące linie:

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

ale tym razem dostałem ten komunikat ostrzegawczy:

Uwaga: Niezdefiniowana zmienna: _SESSION

Czy istnieje lepszy sposób sprawdzenia, czy sesja już się rozpoczęła?

Jeśli użyję, @session_startczy to zadziała poprawnie i po prostu zamknie ostrzeżenia?



Zobacz także odpowiedzi
Stackoverflow

Odpowiedzi:


761

Zalecany sposób dla wersji PHP> = 5.4.0, PHP 7

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

Odniesienie: http://www.php.net/manual/en/function.session-status.php

Dla wersji PHP <5.4.0

if(session_id() == '') {
    session_start();
}

1
Myślę, że jest problem z rozwiązaniem dla PHP <5.4. session_id jest ustawiony PIERWSZA sesja czasowa jest uruchamiana, ale nie jest usuwana po zamknięciu sesji. Na przykład jeśli przed fragmentem znajduje się kod typu session_start();session_write_close();: wtedy warunek if się nie powiedzie, ale nie mamy otwartej sesji ...
Nicolò Martini

@Nicolo Martini Jak rozumiem: sesja rozpoczęta session_start()u góry skryptu jest ZAMKNIĘTA, gdy skrypt kończy się, LUB gdy session_write_closed()jest wywoływana przed zakończeniem skryptu. Tj. Sesja ZAMYKA, gdy dane są zapisywane w pliku cookie sesji, a sesja jest odblokowana w celu uzyskania dostępu przez inny skrypt, który również wywołuje „session_start”. ZAMKNIĘCIE NIE oznacza zatem, że sesja jest ZNISZCZONA. Możesz zamknąć sesję, wychodząc z bieżącego skryptu lub wywołując session_write_close(), i możesz otworzyć ją ponownie, wywołując session_start(). Przynajmniej moje zrozumienie.
Stefan,

1
Czy to wciąż dobry sposób na rozpoczęcie sesji? Ponieważ w linku nie ma nic związanego z tą odpowiedzią
csandreas1

@ csandreas1 zobaczysz z linku opis session_status i jego oczekiwane wartości zwracane. Odpowiedź na twoje pytanie brzmi: tak!
lovelyramos,

W niektórych okolicznościach miałem to niepowodzenie - użyłem if (! Isset ($ _ SESSION)) z powodzeniem
Scott

161

W przypadku wersji PHP wcześniejszych niż PHP 5.4.0:

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

Chociaż, IMHO, naprawdę powinieneś pomyśleć o refaktoryzacji kodu zarządzania sesją, jeśli nie wiesz, czy sesja się rozpocznie ...

To powiedziawszy, moja opinia jest subiektywna i zdarzają się sytuacje (których przykłady opisano w komentarzach poniżej), w których może nie być możliwe ustalenie, czy sesja się rozpoczęła.


37
Niekoniecznie źle jest wiedzieć, czy twoja sesja się rozpoczęła. Jeśli ładujesz się leniwie (zaczynasz sesję tylko wtedy, gdy jest potrzebna), test w odpowiedzi będzie w porządku.
drawm

1
Również w niektórych środowiskach apache ma skonfigurowane automatyczne uruchamianie sesji
LeonardChallis

Przykład testowania, czy session_id () zwraca pusty ciąg w pliku dołączanym:
tgoneil

3
Komentarz dotyczący zarządzania sesją refaktoryzacji, jeśli nie wiesz, czy jest tartowany czy nie, nie jest tak naprawdę istotny. Na przykład, jeśli kodujesz zaawansowane funkcje do motywu WordPress, nigdy nie dowiesz się, czy wtyczka zaczęła już korzystać z sesji bez sprawdzania. Świat kodowania nie zawsze jest taki czarno-biały: P
Jimbo Jonny

Mmm, naprawdę dobre punkty. Przyznaję, że moje komentarze są bardzo subiektywne - zmienię odpowiedź, aby to odzwierciedlić.
Alex

71

PHP 5.4 wprowadził session_status () , który jest bardziej niezawodny niż poleganie na nim session_id().

Rozważ następujący fragment kodu:

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

Tak więc, aby sprawdzić, czy sesja się rozpoczyna, zalecanym sposobem w PHP 5.4 jest teraz:

session_status() == PHP_SESSION_ACTIVE

3
Fragment kodu, który wykorzystuje stan_status, gdy jest dostępny, i starsze metody, kiedy nie wydaje się być idealny tutaj BTW, podpowiedź :)
Jimbo Jonny

1
Dziękujemy za aktualizację Benjamin. Warto wiedzieć, że od PHP 5.4 można zastosować nową metodę.
Logan,

1
Jest to o wiele lepszy sposób na sprawdzenie tego, nie zawsze wiesz, czy masz sesję rozpoczętą, szczególnie gdy użytkownik usuwa pliki cookie, gdy są w trakcie przeglądania witryny ... Zawsze koduję dla 2-latków, ty nigdy nie wiem, co zrobią użytkownicy ;-) Jeśli chodzi o mnie, mam mały plik Config.php, który jest wywoływany we wszystkich moich skryptach w celu ustawienia zmiennych i innych informacji, więc dodanie tego do tego pliku zawsze zapewnia rozpoczęcie sesji, jeśli jest potrzebny
Andy Braham,

35

możesz to zrobić i to jest naprawdę łatwe.

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

Mam nadzieję, że to pomoże :)


6
@zloctb: Nie mogę wymyślić żadnej sytuacji, w której bym to zrobił $_SESSION=array();, więc ta odpowiedź wydaje się dobra.
halfer

5
@halfer Zobacz odpowiedź Ryana. Jeśli session_destroy()został wywołany, $_SESSIONnadal można go ustawić. Ponadto w testach jednostkowych możesz ustawić $_SESSIONbezpośrednio. Ale głosowałem za tym, ponieważ w większości praktycznych sytuacji ta odpowiedź powinna być wystarczająco dobra (dopóki PHP 5.3 nigdy więcej nie będzie widoczne ...)
Darren Cook

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

21

W wersjach wcześniejszych niż PHP 5.4 nie ma innej wiarygodnej metody niż ustawienie flagi globalnej.

Rozważać:

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

Lub:

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.

Tak więc przed PHP 5.4 powinieneś ustawić globalną wartość logiczną.


12

Dla wszystkich wersji php

if ((function_exists('session_status') 
  && session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
  session_start();
}

1
Podobnie można również zrobićif ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Anthony Hatzopoulos

9

Sprawdź to :

<?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();
?>

Źródło http://php.net


6

Użyj session_id () , zwraca pusty ciąg, jeśli nie jest ustawiony. Jest bardziej niezawodny niż sprawdzanie $_COOKIE.

if (strlen(session_id()) < 1) {
    session_start();
}


5

Powinno to działać dla wszystkich wersji PHP. Określa wersję PHP, a następnie sprawdza, czy sesja jest uruchamiana na podstawie wersji PHP. Następnie, jeśli sesja nie zostanie uruchomiona, rozpocznie się.

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

Jedyne, co musisz zrobić, to:

<?php
if(!isset($_SESSION))
{
session_start();
}
?>

Tego używałem przez lata. Ktoś radziłby nie używać tego? Oczywiście dobrze jest sprawdzić, czy sesja jest czasami uruchamiana - w niektórych środowiskach apache ma skonfigurowane automatyczne uruchamianie sesji, leniwe ładowanie (rozpoczynanie sesji tylko wtedy, gdy jest to potrzebne) lub po prostu czasami trzeba zrobić szybki hack
K , Kilian Lindberg

JEST TĘ SAMĄ ODPOWIEDŹ POWYŻEJ (@miyuru)

2

Nie jestem pewien co do wydajności takiego rozwiązania, ale pochodzi z działającego projektu. Jest to również używane, jeśli musisz zdefiniować domyślny język

   /**
    * 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

@ przed wywołaniem funkcji pomija wszelkie błędy, które mogą być zgłaszane podczas wywołania funkcji.

Dodanie @wcześniej session_startmówi PHP, aby uniknąć drukowania komunikatów o błędach.

Na przykład:

Używanie session_start()po tym, jak już coś wydrukowałeś w przeglądarce, powoduje błąd, więc PHP wyświetli coś takiego: „nagłówki nie mogą zostać wysłane: rozpoczęte o (linia 12)”, @session_start()w tym przypadku nadal się nie powiedzie, ale komunikat o błędzie nie jest drukowany na ekran.

Przed dołączeniem plików lub przekierowaniem na nową stronę skorzystaj z exit()funkcji, w przeciwnym razie pojawi się błąd.

Tego kodu można użyć we wszystkich przypadkach:


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

1

W PHP 5.3 to działa dla mnie:

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

to masz. Jeśli nie umieścisz instrukcji „if” na początku, sesja rozpocznie się w jakikolwiek sposób, nie wiem dlaczego.


1

Odpowiedź OPARTA na odpowiedzi @Meliza Ramos (patrz pierwsza odpowiedź) i http://php.net/manual/en/function.phpversion.php ,

DZIAŁANIA:

  • zdefiniuj PHP_VERSION_ID, jeśli nie istnieje
  • zdefiniuj funkcję sprawdzania wersji na podstawie PHP_VERSION_ID
  • Zdefiniuj funkcję bezpieczną dla openSession ()

używaj tylko 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();
    }
}

Właściwie jest już za późno, aby wyjaśnić to tutaj, ponieważ zostało rozwiązane. To był plik .inc jednego z moich projektów, w którym konfigurujesz menu restauracji, wybierając danie i usuwając / dodając lub zmieniając kolejność. Serwer, na którym pracowałem, nie miał rzeczywistej wersji, więc uczyniłem ją bardziej elastyczną. To zależy od autorów, którzy chcą go wykorzystać i wypróbować.


1

Czy ten fragment kodu działa dla Ciebie?

if (!count($_SESSION)>0) {
    session_start();
}

0

Powinieneś zreorganizować swój kod, aby wywoływać session_start()dokładnie raz na wykonanie strony.


4
wywołanie go dokładnie raz na wykonanie strony może nie być pożądane w niektórych sytuacjach.
Timo Huovinen

Jeśli zabijasz sesję, aby ją odtworzyć, to pewnie, ale to wyjątkowy przypadek. Ogólnie rzecz biorąc, aplikacja powinna mieć kod uruchamiany na samym początku, czyli tam, gdzie idzie session_start ().
SamT

1
na przykład aplikacja przechowuje sesje w pliku i musi załadować 2 równoczesne wolne żądania danych, żadne z tych żądań nie potrzebuje sesji, ale jedno zablokuje drugie, ponieważ session_start blokuje plik sesji.
Timo Huovinen,

Dokładnie. @YuriKolovsky ma rację. Pytanie Alexa jest istotne, ponieważ takie przypadki mogą się zdarzyć i nie są rzadkie.
Paulo Coghi - Przywróć Monikę

14
-1, większość stron internetowych jest oparta na CMS i zawiera takie rzeczy, jak motywy i wtyczki, często pisane przez różne podmioty, nigdy nie wiedząc, czy kod nawzajem rozpoczął sesje, czy nie. Implikacja, że ​​jest to tylko problem organizacji kodu, jest fałszywa.
Jimbo Jonny

0
session_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}

0

Wersja PHP_VERSION_ID jest dostępna od wersji PHP 5.2.7, więc sprawdź to najpierw i, jeśli to konieczne, utwórz ją. session_statusjest dostępny od PHP 5.4, dlatego też musimy to sprawdzić:

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

skończyłem z podwójną kontrolą statusu. php 5.4+

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

0

Możesz użyć następującego rozwiązania, aby sprawdzić, czy sesja PHP już się rozpoczęła:

if(session_id()== '')
{
   echo"Session isn't Start";
}
else
{
    echo"Session Started";
}

Prawidłowa odpowiedź jest bardziej szczegółowa.
Clément Prévost

0

Właśnie tego używam do ustalenia, czy sesja się rozpoczęła. Używając pustego i isset w następujący sposób:

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}

-3

Zamień na session_start();:

if (!isset($a)) {
    a = False;
    if ($a == TRUE) {
        session_start();
        $a = TRUE;
    }
}

zawiera błędy w kodzie i działałby tylko wtedy, gdyby ten sam plik był dołączany wiele razy, ale nie w przypadku zamknięcia.
BananaAcid
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.