96

In my PHP code, if a session has already started, and I try to start a new one, I get the following Notice:

Notice: A session had already been started - ignoring session_start()

How can I avoid this?

hakre
  • 193,403
  • 52
  • 435
  • 836
user1400702
  • 975
  • 1
  • 7
  • 6
  • 3
    Don't start a new session if an old one is running? – Madara's Ghost May 18 '12 at 08:10
  • possible duplicate of [How to tell if a session is active?](http://stackoverflow.com/questions/3788369/how-to-tell-if-a-session-is-active) - please use the search before asking a question. – hakre May 18 '12 at 09:19
  • For me it worked simply by removing session_start(), if the session is already started then why do we need to start it again.In my case It was just a config.php file which INCLUDEd in code – Mangesh Sathe Jun 25 '18 at 12:28
  • I've put `session_start()` into one of my includes and `require_once` it in every file that I need. – nurchi May 06 '20 at 18:07

11 Answers11

298

Try

<?php
    if(!isset($_SESSION)) 
    { 
        session_start(); 
    } 
?>
Valeriy Gorbatikov
  • 3,459
  • 1
  • 15
  • 9
37

If you want a new one, then do session_destroy() before starting it. To check if its set before starting it, call session_status() :

$status = session_status();
if($status == PHP_SESSION_NONE){
    //There is no active session
    session_start();
}else
if($status == PHP_SESSION_DISABLED){
    //Sessions are not available
}else
if($status == PHP_SESSION_ACTIVE){
    //Destroy current and start new one
    session_destroy();
    session_start();
}

I would avoid checking the global $_SESSION instead of I am calling the session_status() method since PHP implemented this function explicitly to:

Expose session status via new function, session_status This is for (PHP >=5.4.0)

sqlchild
  • 8,754
  • 28
  • 105
  • 167
Juan Cortés
  • 20,634
  • 8
  • 68
  • 91
7
session_status() === PHP_SESSION_ACTIVE ?: session_start();

Closed Game

Crabthug
  • 71
  • 1
  • 1
5

Only if you want to destroy previous session :

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

or you can use

unset($_SESSION['variable_session _data'])

to destroy a particular session variable.

Code Spy
  • 9,626
  • 4
  • 66
  • 46
2

Yes, you can detect if the session is already running by checking isset($_SESSION). However the best answer is simply not to call session_start() more than once.

It should be called very early in your script, possibly even the first line, and then not called again.

If you have it in more than one place in your code then you're asking to get this kind of bug. Cut it down so it's only in one place and can only be called once.

Spudley
  • 166,037
  • 39
  • 233
  • 307
1

You must of already called the session start maybe being called again through an include?

if( ! $_SESSION)
{
    session_start();
}  
MikeCruz13
  • 1,254
  • 1
  • 10
  • 19
  • 1
    A bit late, but for whatever reason this does not work. Only (!isset($_SESSION)) works. – Mave Oct 05 '13 at 23:16
  • 2
    Risk to fire this: `Notice: Undefined variable: _SESSION`. Use `isset` instead. – T30 Nov 26 '15 at 08:47
1

I encountered this issue while trying to fix $_SESSION's blocking behavior.

http://konrness.com/php5/how-to-prevent-blocking-php-requests/

The session file remains locked until the script completes or the session is manually closed.

So, by default, a page should open a session in read-only mode. But once it's open in read-only, it has to be closed-and-reopened in to get it into write mode.

const SESSION_DEFAULT_COOKIE_LIFETIME = 86400;

/**
 * Open _SESSION read-only
 */
function OpenSessionReadOnly() {
    session_start([
                      'cookie_lifetime' => SESSION_DEFAULT_COOKIE_LIFETIME,
                      'read_and_close'  => true,    // READ ACCESS FAST
                  ]);
    // $_SESSION is now defined. Call WriteSessionValues() to write out values
}

/**
 * _SESSION is read-only by default. Call this function to save a new value
 * call this function like `WriteSessionValues(["username"=>$login_user]);`
 * to set $_SESSION["username"]
 *
 * @param array $values_assoc_array
 */
function WriteSessionValues($values_assoc_array) {
    // this is required to close the read-only session and 
    // not get a warning on the next line.
    session_abort();

    // now open the session with write access
    session_start([ 'cookie_lifetime' => SESSION_DEFAULT_COOKIE_LIFETIME ]);

    foreach ($values_assoc_array as $key => $value) {
        $_SESSION[ $key ] = $value;
    }
    session_write_close();  // Write session data and end session

    OpenSessionReadOnly(); // now reopen the session in read-only mode.
}

OpenSessionReadOnly();  // start the session for this page

Then when you go to write some value:

WriteSessionValues(["username"=>$login_user]);

The function takes an array of key=>value pairs to make it even more efficient.

TrophyGeek
  • 5,902
  • 2
  • 36
  • 33
0
<?php
if ( session_id() != "" ) {
    session_start();
}

Basically, you need to check if a session was started before creating another one; ... more reading.

On the other hand, you chose to destroy an existing session before creating another one using session_destroy().

nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
Odinn
  • 808
  • 5
  • 23
0

try this

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

I suggest you to use ob_start(); before starting any sesson varriable, this should order you browser buffer.

edit: Added an extra ) after $_SESSION

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
user2521037
  • 181
  • 1
  • 2
0

None of the above was suitable, without calling session_start() in all php files that depend on $Session variables they will not be included. The Notice is so annoying and quickly fill up the Error_log. The only solution that I can find that works is this....

    error_reporting(E_ALL ^ E_NOTICE);
    session_start();

A Bad fix , but it works.

0

It would be more efficient:

@session_start();

Avoiding error handler in the screen

Best,

Jos3
  • 1