Vérifiez si la session PHP a déjà démarré


461

J'ai un fichier PHP qui est parfois appelé à partir d'une page qui a démarré une session et parfois à partir d'une page qui n'a pas de session démarrée. Par conséquent, lorsque j'ai session_start()sur ce script, je reçois parfois le message d'erreur pour "session déjà démarrée". Pour cela j'ai mis ces lignes:

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

mais cette fois, j'ai reçu ce message d'avertissement:

Remarque: variable non définie: _SESSION

Existe-t-il un meilleur moyen de vérifier si la session a déjà commencé?

Si j'utilise @session_start, cela fera-t-il fonctionner correctement et fermera-t-il simplement les avertissements?



Voir aussi ces réponses de Stackoverflow: stackoverflow.com/questions/1545357/…
contact-form.co_you_go

Réponses:


761

Méthode recommandée pour les versions de PHP> = 5.4.0, PHP 7

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

Référence: http://www.php.net/manual/en/function.session-status.php

Pour les versions de PHP <5.4.0

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

1
Je pense qu'il y a un problème avec la solution pour PHP <5.4. session_id est défini la première fois que la session démarre, mais il n'est pas supprimé lorsque la session est fermée. Ainsi par exemple, s'il y a, avant votre extrait de code, un code comme session_start();session_write_close();: alors la condition if échoue mais nous n'avons pas de session ouverte ...
Nicolò Martini

@Nicolo Martini Si je comprends bien: une session démarrée avec session_start()en haut d'un script est FERMÉE lorsque le script se termine, OU quand session_write_closed()est appelée avant la fin du script. C'est-à-dire qu'une session se ferme quand ses données sont écrites dans le cookie de session et que la session est déverrouillée pour l'accès par un autre script qui appelle également 'session_start'. LA FERMETURE ne signifie PAS que la session est DÉTROYÉE, par conséquent. Vous pouvez fermer une session en quittant le script en cours ou en appelant session_write_close(), et vous pouvez l'ouvrir à nouveau en appelant session_start(). Ma compréhension, au moins.
Stefan

1
Est-ce toujours un bon moyen de démarrer une session? Parce que dans le lien il n'y a rien de lié à cette réponse
csandreas1

@ csandreas1 vous verrez à partir du lien la description de session_status et ses valeurs de retour attendues. La réponse à ta question est oui!
lovelyramos

J'ai eu cet échec dans certaines circonstances - j'ai utilisé if (! Isset ($ _ SESSION)) avec succès
Scott

161

Pour les versions de PHP antérieures à PHP 5.4.0:

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

Cependant, à mon humble avis, vous devriez vraiment penser à refactoriser votre code de gestion de session si vous ne savez pas si une session est lancée ou non ...

Cela dit, mon opinion est subjective et il existe des situations (dont des exemples sont décrits dans les commentaires ci-dessous) où il peut ne pas être possible de savoir si la session a commencé.


37
Ce n'est pas nécessairement mauvais de ne pas savoir si votre session a commencé. Si vous effectuez un chargement paresseux (en ne démarrant la session que lorsque cela est nécessaire pour la première fois), le test dans votre réponse conviendrait parfaitement.
drewm

1
Également dans certains environnements, apache a configuré le démarrage automatique de la session
LeonardChallis

Un exemple pour tester si session_id () renvoie une chaîne vide dans un fichier include:
tgoneil

3
Le commentaire sur la refactorisation de la gestion de session si vous ne savez pas si elle est tarée ou non n'est pas vraiment pertinent. Par exemple, si vous codez des fonctionnalités avancées dans un thème WordPress, vous ne saurez jamais si un plugin a déjà commencé à utiliser des sessions sans vérification. Le monde du codage n'est pas toujours aussi noir et blanc: P
Jimbo Jonny

Mmm, de bons points en effet. Je reconnais que mes commentaires sont très subjectifs - je modifierai ma réponse pour refléter cela.
Alex

71

PHP 5.4 introduit session_status () , qui est plus fiable que de s'appuyer sur session_id().

Considérez l'extrait de code suivant:

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

Donc, pour vérifier si une session est démarrée, la méthode recommandée en PHP 5.4 est maintenant:

session_status() == PHP_SESSION_ACTIVE

3
Un extrait de code qui utilise session_status lorsqu'il est disponible et des méthodes plus anciennes dans le cas contraire semblent être parfaits ici BTW, hint hint :)
Jimbo Jonny

1
Merci pour la mise à jour Benjamin. Il est bon de savoir qu'une nouvelle méthode peut être utilisée à partir de PHP 5.4.
Logan

1
C'est une bien meilleure façon de vérifier cela, vous ne savez pas toujours si vous avez une session démarrée, surtout lorsque l'utilisateur efface les cookies lorsqu'il est en train de naviguer sur le site ... Je code toujours pour les 2 ans, vous Je ne sais jamais ce que les utilisateurs vont faire ;-) Quant à moi, j'ai un petit fichier Config.php qui est appelé sur tous mes scripts pour configurer des variables et d'autres informations, donc simplement l'ajouter dans ce fichier garantit toujours que la session est lancée si il est nécessaire
Andy Braham

35

vous pouvez le faire, et c'est vraiment facile.

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

J'espère que cela aide :)


6
@zloctb: Je ne peux penser à aucune situation dans laquelle je ferais $_SESSION=array();, donc cette réponse semble correcte.
halfer

5
@halfer Voir la réponse de Ryan. Si session_destroy()a été appelé, il $_SESSIONpeut encore être défini. En outre, dans les tests unitaires, vous pouvez définir $_SESSIONdirectement. Mais j'ai voté pour cela, car pour la plupart des situations pratiques, cette réponse devrait être assez bonne (jusqu'à ce que PHP 5.3 ne soit plus jamais vu ...)
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

Avant PHP 5.4, il n'y a pas de moyen fiable de savoir autre que de définir un indicateur global.

Considérer:

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

Ou:

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.

Donc, avant PHP 5.4, vous devez définir un booléen global.


12

Pour toute version php

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

1
De même, on pourrait aussi faireif ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Anthony Hatzopoulos

9

Vérifiez ça :

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

Source http://php.net


6

Utilisez session_id () , il retourne une chaîne vide s'il n'est pas défini. C'est plus fiable que de vérifier le $_COOKIE.

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


5

Cela devrait fonctionner pour toutes les versions de PHP. Il détermine la version PHP, puis vérifie si la session est démarrée en fonction de la version PHP. Ensuite, si la session n'est pas démarrée, elle la démarre.

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

La seule chose que vous devez faire est:

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

C'est celui que j'ai utilisé au fil des ans. Quelqu'un conseille de ne pas utiliser celui-ci? Bien sûr, il est bon d'utiliser une vérification si la session est démarrée parfois - dans certains environnements, apache a un démarrage automatique de session configuré, un chargement paresseux (ne démarrant la session que lorsque cela est nécessaire) ou simplement qu'il suffit parfois de faire un hack rapide
K Kilian Lindberg

EST LA MÊME RÉPONSE CI-DESSUS (@miyuru)

2

Je ne suis pas sûr de l'efficacité d'une telle solution, mais cela provient du projet en cours. Ceci est également utilisé si vous devez définir la langue par défaut

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

@ avant un appel de fonction supprime toutes les erreurs qui peuvent être signalées pendant l'appel de fonction.

L'ajout d'un @avant session_startindique à PHP d'éviter d'imprimer des messages d'erreur.

Par exemple:

L'utilisation d'une session_start()fois que vous avez déjà imprimé quelque chose dans le navigateur entraîne une erreur, donc PHP affichera quelque chose comme "les en-têtes ne peuvent pas être envoyés: démarré à (ligne 12)", @session_start()échouera toujours dans ce cas, mais le message d'erreur n'est pas imprimé sur écran.

Avant d'inclure les fichiers ou de rediriger vers une nouvelle page, utilisez la exit()fonction, sinon cela donnera une erreur.

Ce code peut être utilisé dans tous les cas:


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

1

Sur PHP 5.3, cela fonctionne pour moi:

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

alors vous avez. Si vous ne mettez pas le pas à si l'instruction commençant la session commencera de toute façon je ne sais pas pourquoi.


1

Réponse BASÉE sur @Meliza Ramos Response (voir première réponse) et http://php.net/manual/en/function.phpversion.php ,

ACTIONS:

  • définir PHP_VERSION_ID s'il n'existe pas
  • définir une fonction pour vérifier la version basée sur PHP_VERSION_ID
  • définir la fonction pour sécuriser openSession ()

utilisez uniquement 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();
    }
}

En fait, il est maintenant trop tard pour l'expliquer ici de toute façon car il a été résolu. Il s'agissait d'un fichier .inc d'un de mes projets où vous configurez un menu pour un restaurant en sélectionnant un plat et en supprimant / ajoutez ou modifiez la commande. Le serveur sur lequel je travaillais n'avait pas la version actuelle, je l'ai donc rendue plus flexible. C'est aux auteurs qui souhaitent l'utiliser et l'essayer.


1

Cet extrait de code vous convient-il?

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

0

Vous devez réorganiser votre code afin d'appeler session_start()exactement une fois par exécution de page.


4
l'appeler exactement une fois par exécution de page peut ne pas être souhaité dans certaines situations.
Timo Huovinen

Si vous tuez la session pour la recréer, alors bien sûr, mais c'est un cas spécial. En général, l'application doit avoir du code qui est exécuté au tout début une fois, c'est là que va la session_start ().
SamT

1
par exemple, une application stocke des sessions dans un fichier et doit charger 2 demandes de données lentes simultanées, aucune de ces demandes n'a besoin de sessions, mais l'une bloquera l'autre car session_start verrouille le fichier de session.
Timo Huovinen

Exactement. @YuriKolovsky a raison. La question d'Alex est pertinente car ces cas peuvent se produire, et ils ne sont pas rares.
Paulo Coghi - Réintègre Monica

14
-1, La plupart des sites Web sont pilotés par CMS et contiennent des éléments tels que des thèmes et des plugins, souvent écrits par différentes parties, sans jamais savoir si le code de l'autre a démarré des sessions ou non. L'implication qu'il s'agit uniquement d'un problème d'organisation de code est fausse.
Jimbo Jonny

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

0

PHP_VERSION_ID est disponible à partir de PHP 5.2.7, alors vérifiez d'abord et si nécessaire, créez-le. session_statusest disponible à partir de PHP 5.4, nous devons donc vérifier cela aussi:

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

je me suis retrouvé avec une double vérification de statut. php 5.4+

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

0

Vous pouvez utiliser la solution suivante pour vérifier si une session PHP a déjà démarré:

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

La réponse valable est plus détaillée.
Clément Prévost

0

C'est ce que j'utilise pour déterminer si une session a commencé. En utilisant vide et isset comme suit:

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

-3

Remplacez session_start();par:

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

il contient des erreurs de code et ne fonctionnerait que si le même fichier était inclus plusieurs fois, mais pas dans une fermeture.
BananaAcid
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.