Tuesday, February 3, 2015

Using the PHP Session in WordPress

WordPress and Sessions

The WordPress platform is totally stateless and provides no support for the use of sessions outside of the cookie that keeps a user logged in.  This is a very good policy and helps keep your blog light and responsive.  Unfortunately there are times that a session might be convenient to hold some data between requests.  If you search online and in the WordPress forums you will find a lot of discussion of this and a few ideas that point in the correct direction.  
The best of these is Frank Verhoeven’s blog Post on this topic which is short and sweet and contains the basic idea.  The comments on this are the real gold.  What I’m providing here is a summary of the facts I’ve found in those comments and much other online study and experimentation.

Getting access to the session if you are not writing a plugin or theme

The simplest way to get access to the session is to add the following lines to wp-config.php before the call to wp-settings:
if (!session_id())
    session_start();
This is what Frank suggested and it works well if you want to get the session for some of your own code and register_globals isn’t set.

What about register_globals?

You’ll hear a lot of talk about the deprecated PHP option register_globals in php.ini and WordPress’s attempts to defeat its use with the wp_unregister_globals function in load.php. WordPress is correct in doing this, so don’t just comment out wp_unregister_globals.
If register_globals is set WordPress will clear all the globals that it are set. Calling session_start will set the $_SESSION global, so if you call it before wp-settiings is run and register_globals is set you will lose your session variables. In most cases this isn’t a problem, but your hosting provider may have turned that option on and you can’t turn it off.
If that’s the case, you can’t put the session_start in wp-config.php. You will need to put it in your code before you need the session. And if you put it elsewhere be sure to remove it from wp-config.php or you will lose your session.

But of course It’s a plugin that needs a session

You can’t put your session_start in wp-config.php if you are intending to distribute your code to others, since you have no access to it and your users might have register_globals set.  In that case you need to hook into an action that takes place after WordPress is loaded but before your code needs the session.  
You can hook into the “init” action, to do that you would add some code like this to your plugin or your theme’s functions.php:
add_action('init', 'myStartSession', 1);
function myStartSession() {
    if(!session_id()) {
        session_start();
    }
}
This code starts the session early in the initialization process, the 1 is the priority to cause this to run before other initialization. The session will be available once this has run.

One last piece in the puzzle

But it’s still missing a crucial piece.  The data stored in the session doesn’t go away when the user logs out or logs into a different account. For that you need to destroy the session.  And of course that requires a couple more hooks.  This results in the following code to start and destroy the session:
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 ();
}

Now the session is yours to use as you wish in your code

To save some data into the session
$_SESSION['myKey'] = "Some data I need later";
And to get that data out at a later time
if(isset($_SESSION['myKey'])) {
    $value = $_SESSION['myKey'];
} else {
    $value = '';
}
I hope this is of help to others who have faced this problem.

No comments:

Post a Comment