Compruebe si la sesión PHP ya ha comenzado

461

Tengo un archivo PHP que a veces se llama desde una página que ha iniciado una sesión y, a veces, desde una página que no tiene sesión iniciada. Por lo tanto, cuando tengo session_start()este script, a veces recibo el mensaje de error para "sesión ya iniciada". Para eso he puesto estas líneas:

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

pero esta vez recibí este mensaje de advertencia:

Aviso: variable indefinida: _SESSION

¿Hay una mejor manera de verificar si la sesión ya ha comenzado?

Si lo uso, ¿ @session_starthará que las cosas funcionen correctamente y simplemente cerrará las advertencias?

Logan
fuente
2
posible duplicado de cómo verifico si se ha ingresado session_start?
Richard Harrison el
Consulte también estas respuestas de Stackoverflow: stackoverflow.com/questions/1545357/…
contact-form.co_you_go

Respuestas:

761

Forma recomendada para versiones de PHP> = 5.4.0, PHP 7

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

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

Para versiones de PHP <5.4.0

if(session_id() == '') {
    session_start();
}
lovelyramos
fuente
1
Creo que hay un problema con la solución para PHP <5.4. session_id se establece la PRIMERA vez que se inicia la sesión, pero no se elimina cuando se cierra la sesión. Entonces, por ejemplo, si hay, antes de su fragmento, un código como session_start();session_write_close();: entonces la condición if falla pero no tenemos sesión abierta ...
Nicolò Martini
@Nicolo Martini Según tengo entendido: una sesión iniciada session_start()en la parte superior de un script está CERRADA cuando el script sale, O cuando session_write_closed()se llama antes de que el script salga. Es decir, una sesión CIERRA cuando sus datos se escriben en la cookie de sesión y la sesión se desbloquea para que otra secuencia de comandos acceda a ella y también llame a 'session_start'. CERRAR NO significa que la sesión esté DESTRUIDA, por lo tanto. Puede cerrar una sesión saliendo de la secuencia de comandos actual o llamando session_write_close(), y puede volver a abrirla llamando session_start(). Mi comprensión, al menos.
Stefan
1
¿Sigue siendo una buena manera de comenzar una sesión? Porque en el enlace no hay nada relacionado con esta respuesta
csandreas1
@ csandreas1 verá desde el enlace la descripción de session_status y sus valores de retorno esperados. ¡La respuesta a tu pregunta es sí!
lovelyramos
He tenido este fallo en algunas circunstancias - He usado if (! Isset ($ _ SESSION)) con éxito
Scott
161

Para versiones de PHP anteriores a PHP 5.4.0:

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

Sin embargo, en mi humilde opinión, realmente debería pensar en refactorizar el código de administración de la sesión si no sabe si una sesión se inicia o no ...

Dicho esto, mi opinión es subjetiva, y hay situaciones (ejemplos de los cuales se describen en los comentarios a continuación) en las que puede no ser posible saber si se inicia la sesión.

Alex
fuente
37
No es necesariamente malo no saber si se inició su sesión. Si tiene una carga lenta (solo comienza la sesión cuando se necesita por primera vez), entonces la prueba en su respuesta estaría perfectamente bien.
drewm
1
También en algunos entornos, Apache tiene configurado el inicio automático de sesión
LeonardChallis
Un ejemplo para probar si session_id () devuelve una cadena vacía en un archivo de inclusión:
tgoneil
3
El comentario sobre la refactorización de la administración de la sesión si no sabe si está tartada o no, no es realmente relevante. Por ejemplo, si codifica funciones avanzadas en un tema de WordPress, nunca sabrá si un complemento ya ha comenzado a usar sesiones sin verificar. El mundo de la codificación no siempre es tan blanco y negro: P
Jimbo Jonny
Mmm, buenos puntos de hecho. Reconozco que mis comentarios son muy subjetivos; enmendaré mi respuesta para reflejar esto.
Alex
71

PHP 5.4 introdujo session_status () , que es más confiable que confiar en él session_id().

Considere el siguiente fragmento:

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

Entonces, para verificar si se inicia una sesión, la forma recomendada en PHP 5.4 es ahora:

session_status() == PHP_SESSION_ACTIVE
Benjamín
fuente
3
Un fragmento de código que utiliza session_status cuando estén disponibles y los métodos más antiguos cuando no parecería ser perfecta aquí Por cierto, pista pista :)
Jimbo Jonny
1
Gracias por la actualización Benjamin. Es bueno saber que se puede usar un nuevo método a partir de PHP 5.4.
Logan
1
Esta es una forma mucho mejor de verificar esto, no siempre sabes si tienes una sesión iniciada, especialmente cuando el usuario borra las cookies cuando están navegando por el sitio ... Siempre codifico para niños de 2 años, tú nunca sé qué van a hacer los usuarios ;-) En cuanto a mí, tengo un pequeño archivo Config.php que se llama en todos mis scripts para configurar variables y otra información, por lo que solo agregar esto en ese archivo siempre asegura que la sesión se inicie si se necesita
Andy Braham
35

puedes hacer esto, y es realmente fácil.

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

Espero eso ayude :)

miyuru
fuente
66
@zloctb: No puedo pensar en ninguna situación en la que lo haría $_SESSION=array();, por lo que esta respuesta parece estar bien.
halfer
55
@halfer Ver la respuesta de Ryan. Si session_destroy()se ha llamado, $_SESSIONaún podría establecerse. Además, en las pruebas unitarias puede establecer $_SESSIONdirectamente. Pero voté por esto, ya que para la mayoría de las situaciones prácticas, esta respuesta debería ser lo suficientemente buena (hasta que PHP 5.3 nunca más se vea ...)
Darren Cook
22
if (version_compare(phpversion(), '5.4.0', '<')) {
     if(session_id() == '') {
        session_start();
     }
 }
 else
 {
    if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }
 }
k.bon
fuente
21

Antes de PHP 5.4, no hay una forma confiable de conocer más que establecer una bandera global.

Considerar:

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

O:

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.

Entonces, antes de PHP 5.4, debe establecer un valor booleano global.

RY
fuente
12

Para todas las versiones de php

if ((function_exists('session_status') 
  && session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
  session_start();
}
supersuphot
fuente
1
Del mismo modo, uno también podría hacerloif ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Anthony Hatzopoulos,
9

Mira esto :

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

Fuente http://php.net

Elshan
fuente
6

Use session_id () , devuelve una cadena vacía si no se establece. Es más confiable que verificar el $_COOKIE.

if (strlen(session_id()) < 1) {
    session_start();
}
Wesley van Opdorp
fuente
5
if (session_id() === "") { session_start(); }

Espero eso ayude !

Mahesh Cheliya
fuente
5

Esto debería funcionar para todas las versiones de PHP. Determina la versión de PHP, luego verifica si la sesión se inicia según la versión de PHP. Luego, si la sesión no se inicia, la inicia.

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();
    }
  }
}
Dustin Poissant
fuente
4

Lo único que debes hacer es:

<?php
if(!isset($_SESSION))
{
session_start();
}
?>
usuario3140580
fuente
Este es el que he usado a lo largo de los años. ¿Alguien aconseja no usar este? Por supuesto, es bueno usar una verificación si la sesión se inicia a veces: en algunos entornos, apache tiene una configuración de inicio automático de sesión, carga lenta (solo comienza la sesión cuando se necesita por primera vez) o simplemente que a veces solo se necesita hacer un truco rápido
K Kilian Lindberg
ES LA MISMA RESPUESTA ANTERIOR (@miyuru)
2

No estoy seguro de la eficacia de dicha solución, pero esto es del proyecto en funcionamiento. Esto también se usa si necesita definir el idioma predeterminado

   /**
    * Start session
    * Fall back to ukrainian language
    */
   function valid_session() {
    if(session_id()=='') {
        session_start();
        $_SESSION['lang']='uk';
        $_SESSION['lang_id']=3;
    }
    return true;
  }
Alex Khimich
fuente
2

@ antes de que una llamada a función suprima cualquier error que pueda ser reportado durante la llamada a función.

Agregar un @antessession_start le dice a PHP que evite imprimir mensajes de error.

Por ejemplo:

El uso session_start()después de que ya haya impreso algo en el navegador da como resultado un error, por lo que PHP mostrará algo como "no se pueden enviar encabezados: comenzó en (línea 12)",@session_start() aún fallará en este caso, pero el mensaje de error no se imprime en pantalla.

Antes de incluir los archivos o redirigir a una nueva página, use el exit() función; de lo contrario, se producirá un error.

Este código se puede usar en todos los casos:


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

En PHP 5.3 esto funciona para mí:

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

entonces tiene. Si no pone la declaración de no comenzar si la sesión comenzará de alguna manera, no sé por qué.

Lucas M. Oliveira
fuente
1

Respuesta BASADA en @Meliza Ramos Response (ver primera respuesta) y http://php.net/manual/en/function.phpversion.php ,

COMPORTAMIENTO:

  • define PHP_VERSION_ID si no existe
  • defina la función para verificar la versión basada en PHP_VERSION_ID
  • define la función para openSession () seguro

solo use 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();
        }
    }

fuente
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 realidad, ahora es demasiado tarde para explicarlo aquí de todos modos, ya que se ha resuelto. Este fue un archivo .inc de uno de mis proyectos donde configuró un menú para un restaurante seleccionando un plato y eliminando / agregando o cambiando el orden. El servidor en el que estaba trabajando no tenía la versión real, así que lo hice más flexible. Depende de los autores que deseen usarlo y probarlo.

Thielicious
fuente
1

¿Te sirve este fragmento de código?

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

Debe reorganizar su código para que llame session_start()exactamente una vez por ejecución de página.

SamT
fuente
44
llamarlo exactamente una vez por ejecución de página puede no ser deseable en algunas situaciones.
Timo Huovinen
Si está matando la sesión para recrearla, entonces seguro, pero ese es un caso especial. En general, la aplicación debe tener un código que se ejecute al principio una vez, que es donde va la session_start ().
SamT
1
por ejemplo, una aplicación almacena sesiones en un archivo y necesita cargar 2 solicitudes de datos lentas concurrentes, ninguna de estas solicitudes necesita sesiones, pero una bloqueará a la otra porque session_start bloquea el archivo de sesión.
Timo Huovinen
Exactamente. @YuriKolovsky tiene razón. La pregunta de Alex es pertinente porque estos casos pueden suceder y no son infrecuentes.
Paulo Coghi - Restablece a Monica
14
-1, la mayoría de los sitios web están controlados por CMS y tienen elementos como temas y complementos, a menudo escritos por diferentes partes, sin saber si el código del otro ha iniciado sesiones o no. La implicación de que este es un problema de organización de código solamente es falso.
Jimbo Jonny el
0
session_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}
Sukanya Suku
fuente
0

PHP_VERSION_ID está disponible a partir de PHP 5.2.7, así que verifíquelo primero y, si es necesario, créelo . session_statusestá disponible a partir de PHP 5.4, así que tenemos que verificar esto también:

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();
    }
}
Christian Kruse
fuente
0

Según mi práctica, antes de acceder al $_SESSION[]debe llamar session_startcada vez para usar el script. Consulte el siguiente enlace para ver el manual.

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

Para mí al menos session_startes confuso como un nombre. A session_loadpuede ser más claro.

Eduard Hasanaj
fuente
0

Terminé con una doble verificación de estado. php 5.4+

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

Puede usar la siguiente solución para verificar si una sesión PHP ya ha comenzado:

if(session_id()== '')
{
   echo"Session isn't Start";
}
else
{
    echo"Session Started";
}
Manjeet Kumar Nai
fuente
La respuesta válida es más detallada.
Clément Prévost
0

Esto es lo que uso para determinar si una sesión ha comenzado. Mediante el uso de vacío e isset de la siguiente manera:

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}
Rotimi
fuente
-3

Reemplazar session_start();con:

if (!isset($a)) {
    a = False;
    if ($a == TRUE) {
        session_start();
        $a = TRUE;
    }
}
Harshit Chaturvedi
fuente
contiene errores de código y solo funcionaría si el mismo archivo se incluyera varias veces, pero no si se encuentra dentro de un cierre.
BananaAcid