ericmann/wp-session-manager — pull request #18 by kyle-ilantzis (2014-04-11 04:16:14+00:00)
Title: Recursive_ArrayAccess must implement Iterable and must NOT do dirty checking

I encountered problems when using this plugin to replace $_SESSION. Below I explain the problems and their solution.

1. Recursive_ArrayAccess should implement Iterable and Countable.
2. NO dirty checking

[1] Recursive_ArrayAccess should implement Iterable and Countable rather than its subclass WP_Session. If you have associative arrays of associative arrays of ... (and so on) then you cannot do for each loops on the children of WP_Session. For example:

$wp_session = WP_Session::getInstance();

$wp_session["foo"] = array(); // remember $wp_session["foo"] turns into a Recursive_ArrayAccess instance

$wp_session["foo"]["bar"] = array(); // so is $wp_session["foo"]["bar"] a Recursive_ArrayAccess instance

for ($wp_session as $key => $value) {
// this works.
}

for ($wp_session["foo"] as $key => $value) {
// nope,recall $wp_session["foo"] is now an instance of Recursive_ArrayAccess
// which is not iterable.
}

for ($wp_session["foo"]["bar"] as $key => $value) {
// nope,recall $wp_session["foo"]["bar"] is now an instance of
// which is not iterable.
}

So as a result I moved the Iterable and Countable implementations out of the subclass WP_Session and into the super class Recursive_ArrayAccess.

[2] The dirty checking logic does not work. Consider the following:

$wp_session = WP_Session::getInstance(); // Here we read a fresh new session
$wp_session["foo"] = "bar"; // now $wp_session is dirty

VS.

$wp_session = WP_Session::getInstance(); // Here we read an existing session
// which looks like say:
// $wp_session (
// "foo" => Recursive_ArrayAccess (
// "bar" => 0
// ...

$wp_session["foo"]["bar"] = 2; // yes, $wp_session["foo"] is dirty but not $wp_session

Solution? Well Recursive_ArrayAccess can instead have an instance function *isDirty* which could be:

public function isDirty() {
return $this->dirty || if any X in $this[X] is instance of Recursive_ArrayAccess and $this[X]->isDirty()
}

This solves the problem above, but what about objects even at the first level?

$wp_session = WP_Session::getInstance(); // Here we read an existing session
// which looks like say:
// $wp_session (
// "foo" => MyObject (
// $x
// ...

$wp_session["foo"]->setX(...); // nope, $wp_session is not dirty

So basically dirty checking wont work. Therefore I removed the if(dirty) in WP_Session:write_data