WP and Session Keys

Now here’s a strange one.

Much has been written about using sessions in WordPress. Here for example. Simple, straightforward and to the point. And I was pretty sure I’d had it working just by putting

session_start()

at the top of my main plugin file. Not the best way, I suppose, so I took the advice of the person (Peter, apparently) who wrote the op. cit. And it didn’t work.

This didn’t seem to make any sense at all. A little investigation seemed to show that register_globals wasn’t causing the problem, but nothing I could find on the web threw any light on the situation.

The plugin was a simple generic wizard structure, collecting a bit more data on each page and accumulating it in the $_SESSION global variable — or at least, it should have been. At the end of each bit of processing (simplifying slightly) there was a

$_SESSION[] = $answers;

statement. The idea was that at the end the $_SESSION array would look something like:

_SESSION = Array (
    [0] => (first answer)
    [1] => (second answer)
    ...
)

but what was actually happening was that each time through the process (on each page of the wizard, in effect), the new entry was being added but all previous entries were lost! So on the third time through I would have:

_SESSION = Array (
    [] => (third answer)
)

and nothing else.

Then I remembered that when it had last been working I had been using hard-coded strings as the array keys. I wondered if the problem might be that as $_SESSION was (probably) not really an array at all, perhaps it didn’t behave much like one either. Which might explain why the

$element[] = ...

syntax didn’t work. Accordingly I tried putting in explicit indexes, as in:

$_SESSION[$i] = $answers;    // $i is an integer

Still no luck!

Finally there was only one more thing I could think of trying. It was stupid, but when you’ve tried all the sensible things…

$_SESSION["'$i'"] = $answers;

And it worked!

This was actually a mistake on my part. What I had meant to do was to have a string containing only an integer, whereas what I had written was simply a string that included a number (and a couple of single-quote characters). So to be sure I then tried

$_SESSION["$i"] = $answers;

and it didn’t work.

So there you are. Perhaps you already knew this, but I didn’t. Evidently the keys to the $_SESSION array cannot be numeric. They can for other arrays (or more accurately, PHP arrays can be indexed numerically). Try this for example:

<?php
fred = Array (1 => 'one', 2 => 'two');
echo "fred = ";
print_r($fred);

It will behave just as you would expect:

fred = Array ( [1] => one [2] => two )

But replace $fred with $_SESSION, and it no longer works.

Nothing to do with WordPress then. Just don’t try to index the $_SESSION array numerically. Stick to strings and you’ll be fine, but not if the string is simply a number represented as a string!

Notes
  1. This behaviour is mentioned in the comment here.
  2. A much more elegant work-around is to use:
$_SESSION['answers'][] = $answers;

which does work, and gives genuine numerically consecutive keys, albeit at the next level down, and can be unscrambled with the highly readable:

foreach ($_SESSION['answers'] as $answers) {
    ...
}

Close enough!