Why does $_SESSION only work when I am logged in?

WordPress doesn’t use PHP sessions, so WordPress itself can not be related with your sessions working or not regarding if you are logged in or not (I think).

Try to call session_start() on init action instead of doing it in a template file and be sure it is called before your custom library is loaded. Also, it can be interesting to end the PHP session on user log in and user log out to start a fresh one:

add_action('init', 'cyb_start_session', 1);
add_action('wp_logout', 'cyb_end_session');
add_action('wp_login', 'cyb_end_session');

function cyb_start_session() {
    if( ! session_id() ) {
        session_start();
        // now you can load your library that use $_SESSION
    }
}

function cyb_end_session() {
    session_destroy();
}

Because you library calls session_start(), con avoid to call it yourself but you still needs to load your library on init and destroy sessions on log in/log out:

add_action('init', 'cyb_start_session', 1);
add_action('wp_logout', 'cyb_end_session');
add_action('wp_login', 'cyb_end_session');

function cyb_start_session() {
      // load your libreary here (assuming it calls session_start())
}

function cyb_end_session() {
    session_destroy();
}

The key is to start PHP sessions as earlier as possible, before output anything. On init with priority 1 is the earliest it can be done in WP enviroment. If you do before, session can be destroyed by wp_unregister_GLOBALS().

A basic and silly but working example:

add_action('init', 'cyb_start_session', 1);
add_action('wp_logout', 'cyb_end_session');
add_action('wp_login', 'cyb_end_session');

function cyb_start_session() {
    if( ! session_id() ) {
        session_start();
        // now you can use $_SESSION
        $_SESSION['test'] = "test";
    }
}

function cyb_end_session() {
    session_destroy();
}


// This will print array(1) { ["test"]=> string(4) "test" }
// above the content of any post
add_filter( 'the_content', function( $content ) {

        var_dump($_SESSION);

        return $content;

} );

Leave a Comment