27

I'm creating a bilingual site and have decided to use session_start to determine the language of the page using the following:

session_start();    
if(!isset($_SESSION['language'])){
    $_SESSION['language'] = 'English'; //default language
}

The problem with this is that it clashes with Wordpress and I get the following:

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/neurosur/public_html/v2/wp-content/themes/default/header.php:8) in /home/neurosur/public_html/v2/wp-content/themes/default/region.php on line 13

Is there a way to get around this?

Rob
  • 6,304
  • 24
  • 83
  • 189
  • 1
    Sure, don't do any output before calling session_start(). Which means you need to buffer everything WP produces up until the session_start call, or insert your session_start earlier in the rendering chain. – Marc B Aug 03 '12 at 14:09
  • @MarcB I've tried this several times but can never manage to get it to work. – Rob Aug 03 '12 at 14:15

6 Answers6

53

EDIT

Wordpress sends header info before the header.php file is run. So starting the session in the header.php may still conflict with the header info that wordpress sends. Running it on init avoids that problem. (From jammypeach's comment)

Write the following code in your functions.php file:

function register_my_session()
{
  if( !session_id() )
  {
    session_start();
  }
}

add_action('init', 'register_my_session');

Now if you want to set data in session, do like this

$_SESSION['username'] = 'rafi';
rafi
  • 1,493
  • 3
  • 31
  • 43
  • There is an error in your code, you forgot the semicolon after session_start(). You should correct it. – Gfra54 Feb 09 '15 at 15:27
  • 6
    this is the better answer - wordpress sends headers before the header.php file is run, so starting the session there may still clash with the headers wordpress sends. Running it on init avoids that problem. – totallyNotLizards Feb 17 '16 at 09:36
  • 3
    init hook is better for session_start. – Rinku Aug 13 '16 at 08:28
15

I've changed my original answer to the correct one from @rafi (see below).

Write the following code in your functions.php file:

function register_my_session()
{
  if( !session_id() )
  {
    session_start();
  }
}

add_action('init', 'register_my_session');
kpotehin
  • 1,025
  • 12
  • 21
14

I found an interesting article by Peter here. I'm using the following code in my functions.php:

add_action('init', 'myStartSession', 1);
add_action('wp_logout', 'myEndSession');
add_action('wp_login', 'myEndSession');

function myStartSession() {
    if(!session_id()) {
        session_start();
    }
}

function myEndSession() {
    session_destroy ();
}

This destroys old session when user logs out then in again with different account.

Angel Politis
  • 10,955
  • 14
  • 48
  • 66
j.c
  • 2,825
  • 3
  • 31
  • 45
2

Based on this answer and the answers given here, it's best to use the following code snippets:

For versions of PHP >= 5.4.0, PHP 7:

function register_my_session() {
    if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }
}
add_action('init', 'register_my_session');

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


For versions of PHP < 5.4.0:

function register_my_session() {
    if(session_id() == '') {
        session_start();
    }
}
add_action('init', 'register_my_session');

Reference: https://www.php.net/manual/en/function.session-id.php


I don't want to take any credits, I just felt like sharing this information would be helpful.

Daan
  • 2,680
  • 20
  • 39
1

for PHP version 7.4

function register_my_session() {

    if (session_status() === PHP_SESSION_NONE && session_status() !== PHP_SESSION_ACTIVE) {
        @session_start();
    } 
} 
add_action('init', 'register_my_session');
helvete
  • 2,455
  • 13
  • 33
  • 37
Vyshnav MK
  • 131
  • 1
  • 5
1
add_action('init', 'customSessionStart', 1);
add_action('wp_logout', 'customSessionDestroy');
add_action('wp_login', 'customSessionDestroy');
function customSessionStart()
{
    if (!session_id()) {
        session_start();
    }
}
function customSessionDestroy()
{
    session_destroy();
}

When you use this code, you may get the critical issue in the WP Site Health Status. The error says that;

A PHP session was created by a session_start() function call. This interferes with REST API and loopback requests. The session should be closed by session_write_close() before making any HTTP requests.

To suppress this error, you may make this revision when you want to start a session in the WP;

session_start([
    'read_and_close' => true,
]);
Mahdi Zarei
  • 5,644
  • 7
  • 24
  • 54
  • 1
    Setting 'read_and_close' will only be helpful if you don't need to make any changes to the $_SESSION data at a later point. Calling 'read_and_close' will cause any attempt to store data to $_SESSION after calling session_start(['read_and_close' => true]) to silently fail. – fred2 May 30 '23 at 03:20