PHP: Wordpress and $_SESSION

Okay, so I promised some wordpress and CSS stuff, but the CSS stuff will have to wait for a while, till I’ve got some time to actually write up the essay that it’s going to probably be. Instead I’ll quickly go through a problem I had today with wordpress.

I’ve was asked to quickly put together a site for a client that my company has. They were asking for a quick turn around and they were specific in what theme and plugins/widgets they wanted. One of the requirements was that they’re able to capture extra info during the user registration process, but they also wanted it to look the same as the wordpress theme. Currently, if you theme your page, but go to the login page, you're greeted with the dull standard wordpres page and logo. So installed ‘theme-my-login’ and ‘register-plus’ which helped me achieve these things.

Now the problem I ran into was when the captcha from the register-plus plugin, was put into effect on the registration page. The code would generate the graphic from some random letters and numbers, which is pretty standard stuff really. The string that the captcha was generated from, is then stored in the $_SESSION global for validation purposes.

In the dashboard, for the Register-plus plugin, its says “You may need to add the code session_start(); to the top line of the wp_login.php file to enable Simple CAPTCHA to work correctly”. So I added the session_start() function to wp_login.php. So as I said before, the captcha string is sent to the $_SESSION global, which has been initialised by session_start() . What's suppose to happen, is that the page POSTS the info to itself and a confirmation email is suppose to be sent off to the person registering, etc. What was actually happening, was after I had submitted the registration page, I was being told that my captcha code was wrong. After a bit of snooping around and adding in some debugging, I found out that the $_SESSION variable was initialised with session_start() and it even had the elements that had values assigned to it, but all the values that had been assigned were gone.

So I did some snooping through the code and this is what I found. One of the first lines of code in wp-login.php is the following:

require( dirname(__FILE__) . '/wp-load.php' );

So we go have a look in wp-load.php and in that we find the following inside a if statement:
require_once( ABSPATH . 'wp-config.php' );

So now we go snooping in wp-config.php and WAAAAY at the bottom of the file, we see the following:
require_once(ABSPATH . 'wp-settings.php');

And inside wp-settings.php, we find the following:
/**
 * Turn register globals off.
 *
 * @access private
 * @since 2.1.0
 * @return null Will return null if register_globals PHP directive was disabled
 */
function wp_unregister_GLOBALS() {
 
        if ( !ini_get('register_globals') )
                return;
 
        if ( isset($_REQUEST['GLOBALS']) )
                die('GLOBALS overwrite attempt detected');
 
        // Variables that shouldn't be unset
        $noUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', 
                '_SERVER', '_ENV', '_FILES', 'table_prefix');
 
        $input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, 
                $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
        foreach ( $input as $k => $v ) {
                if ( !in_array($k, $noUnset) && isset($GLOBALS[$k]) ) {
                        $GLOBALS[$k] = NULL;
                        unset($GLOBALS[$k]);
                }
        }
}
 
wp_unregister_GLOBALS();

So what we have here, is a function that clears up all globals, including all my $_SESSION values that I’ve inserted in. Now this function is obviously there for a reason, I haven’t really gone into it too much, I assume it’s to make sure that all that your session is clean when you login and don’t have any old data, but that’s just a guess. The problem is, it’s messing with my login captcha, so we can’t just not call it. If we actually take a look at the code, we’ll notice that an array is built of variables to exclude from being unset.
So we add our element in the $_SESSION array to the list. Let’s say that the $_SESSION var was assigned like this:

	$_SESSION[‘captcha’] = $captchaString;

We then add that to the list of variables to ignore.
	$noUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', 
                '_SERVER', '_ENV', '_FILES', 'table_prefix', 'captcha');

After we add, that we reload the page, try registration again and voila, it works.

Now this is by no means the ultimate way of doing things, it’s just a quick hack up that I had to come up with to achieve something in a quick turnaround. Ideally we want to only add that exception in under certain circumstances, like if there is captcha involved. We also, should probably empty $_SESSION var once we have logged in properly.

I’ll probably get to that when I have a couple spare minutes sometime this week, but I’m just saying that if you’re having the same problem, you know where to start looking.

I’m playing with Drupal atm in my own time, so I’m hoping to have a few howto’s coming up for building modules and themes coming up for that too. You should in process see some changes happening to the blog.

Syn