An implementation of the memento pattern in PHP

Written by Ben Wendt

The memento pattern is a design pattern used to store and revert states for objects which support this capacity. It is accomplished by having a Caretaker object which manages a set of states, encoded in Memento objects. The Memento objects handle the storage of state; the implementation of this can vary, but it necessitates some level of deep-copying the object. A shallow copy will not suffice in general because it will not always capture the whole state of an object, due to the fact that most languages implement memory access for objects as references. Because of this, I use serialize and unserialize in my example below. Of course you could use other methods, like clone or just copying what you know you will need if memory is a concern.

Let’s take a look at how it works…

/**
* The memento class is very simple; it simply serializes and
* unserializes incoming data.
*/

class Memento {
    private $state = null;
    public function __construct($state) {
        $this->state = serialize($state);
    }
    public function revertState() {
        return unserialize($this->state);
    }
}

/**
* The Caretaker class manages a group of Memento objects.
*/

class Caretaker {

    private $states = array();

    public function set($state) {
        $this->states[] = new Memento($state);
    }

    public function get() {
        $memento = array_pop($this->states);
        return $memento->revertState();
    }

}

And here is a sample of usage:

$ct = new Caretaker();

$ct->set('3');
$ct->set('2');
$ct->set('1');
$ct->set(new stdClass);

var_dump($ct->get());
echo $ct->get() . "n";
echo $ct->get() . "n";
echo $ct->get() . "n";