Using the Memento Pattern in PHP
The memento pattern is a behavioral design pattern which lets you save and restore an object to its previous state without compromising its privacy.
Article Highlights
- The memento pattern delegates creating a snapshot to the original object while keeping the state in a memento object.
- Benefit – Doesn’t violate the data encapsulation of the original objects.
- Con – Creating memento objects too often can consume much memory.
Memento Design Pattern PHP Code Example
<?php
interface Originator {
public function createSnapshot();
}
// The originator class
class WhiteBoard implements Originator {
private $fontSize;
private $fontFamily;
private $canvasSize;
private $canvasColor;
private $output;
//More fields...
function __construct($fontSize, $fontFamily, $canvasSize, $canvasColor, $output) {
$this->fontSize = $fontSize;
$this->fontFamily = $fontFamily;
$this->canvasSize = $canvasSize;
$this->canvasColor = $canvasColor;
$this->output = $output;
}
function setFontSize($fontSize) {
$this->fontSize = $fontSize;
}
function setFontFamily($fontFamily) {
$this->fontFamily = $fontFamily;
}
function setCanvasSize($canvasSize) {
$this->canvasSize = $canvasSize;
}
function setCanvasColor($canvasColor) {
$this->canvasColor = $canvasColor;
}
function setOutput($output) {
$this->output = $output;
}
function getStateInfo() {
return "\nFont Size: ".$this->fontSize."\nFont Family: ".$this->fontFamily.
"\nCanvas Size: ".$this->canvasSize."\nCanvas Color: ".$this->canvasColor."\nOutput Format: ".$this->output."\n\n";
}
// Saves the state to the momento
function createSnapshot() {
//Passes reference to itself and fields.
return new SnapShot($this, $this->fontSize, $this->fontFamily, $this->canvasSize, $this->canvasColor, $this->output);
}
//More methods....
}
interface Memento {
public function restore();
}
// The memento class
class SnapShot implements Memento {
private $whiteboard;
private $fontSize;
private $fontFamily;
private $canvasSize;
private $canvasColor;
private $output;
function __construct($whiteboard, $fontSize, $fontFamily, $canvasSize, $canvasColor, $output) {
$this->whiteboard = $whiteboard;
$this->fontSize = $fontSize;
$this->fontFamily = $fontFamily;
$this->canvasSize = $canvasSize;
$this->canvasColor = $canvasColor;
$this->output = $output;
}
//Restores the originator state by passing the stored set of fields to the setter functions.
function restore() {
$this->whiteboard->setFontSize($this->fontSize);
$this->whiteboard->setFontFamily($this->fontFamily);
$this->whiteboard->setCanvasSize($this->canvasSize);
$this->whiteboard->setCanvasColor($this->canvasColor);
$this->whiteboard->setOutput($this->output);
}
}
//The UndoCommand act as a caretaker.
class UndoCommand {
private $memento;
function createSnapshot($whiteboard) {
$this->memento = $whiteboard->createSnapshot();
}
function undo() {
//If memento exists
if($this->memento) {
$this->memento->restore();
}
}
}
function main() {
$whiteboard = new Whiteboard('20px', 'Arial', '1000px', 'White', 'png');
$undoCommand = new UndoCommand();
echo "Initial State: ".$whiteboard->getStateInfo();
//Creates snapshot of the initial state
$undoCommand->createSnapshot($whiteboard);
//New state
$whiteboard->setFontSize('11px');
$whiteboard->setFontFamily('Times new roman');
$whiteboard->setCanvasSize('800px');
$whiteboard->setCanvasColor('Brown');
$whiteboard->setOutput('jpeg');
echo "New State: ".$whiteboard->getStateInfo();
//Reverts whiteboard to initial state
$undoCommand->undo();
echo "Reverted State: ".$whiteboard->getStateInfo();
}
/*
OUTPUT
Initial State:
Font Size: 20px
Font Family: Arial
Canvas Size: 1000px
Canvas Color: White
Output Format: png
New State:
Font Size: 11px
Font Family: Times new roman
Canvas Size: 800px
Canvas Color: Brown
Output Format: jpeg
Reverted State:
Font Size: 20px
Font Family: Arial
Canvas Size: 1000px
Canvas Color: White
Output Format: png
*/
?>

Table of Contents
- What is the Memento Pattern?
- Memento Pattern Example
- Problem 🙁
- Solution 🙂
- Benefits of the Memento Pattern
- Complete Architecture of Memento Pattern
- Pseudocode of Memento Pattern
- Pros and Cons of the Memento Pattern
- Use cases of Memento pattern
- Conclusion
What is the Memento Pattern
“The memento pattern is a behavioral design pattern which lets you save and restore an object to its previous state without compromising its privacy.”

Memento Pattern Example
Imagine that we are building a whiteboard tool. The whiteboard has several options, including font size & family, canvas size & colour and output format. Users can take a snapshot of their whiteboard and can undo it.

The application saves these snapshots in storage and retrieves them when a user chooses to revert from the current state.
An easy way to implement this functionality is to loop through the object fields and copy them over to the storage. This approach sounds straightforward and may work if the object provides a way to access all its fields, but there are many concerns from a design perspective.
Problem 🙁
Single responsibility principle
“A class should have one and only one responsibility.”, states the single responsibility principle. Merging the save & retrieve methods with an unrelated set of methods increases the cohesion of a class. A highly cohesive module is more generalised with more than one aspect of the operation.
What’s the problem with high cohesion? The issue comes when parts of your application change. If a module does much more than it is supposed to, this change will likely affect it. We want to limit the scope of changes in a system to avoid an avalanche effect.
So, in terms of this principle, the state management should sit in a separate module than co-existing with other unrelated sets of operations.
Open-closed principle
“A class should be closed for modification but open for extension.”, states the open/closed principle. Suppose we refactor the Whiteboard class in the future, adding or removing fields. Such changes will force us to modify the methods which save and restores the state. Adding more classes to the design will also affect the whole system.
Moreover, using a direct approach tends to use concrete classes rather than abstractions, which is another red flag regarding the degree of the system’s flexibility.
Data encapsulation
Data hiding or encapsulation is important in object-oriented programming (OOP). An object has control over what data to hide and what to expose. Usually, there is a mix of private and public fields and methods in a class. A class defines an interface for external entities.
An interface typically doesn’t reveal the internal details but provides a point of interaction for external objects and entities.
Generally speaking, from a security perspective, a process or entity should have only the bare minimum privileges to perform intended functions. This statement is a fundamental principle called the principle of least privilege. So exposing data of a class is a negation of this principle.
The direct approach we have been discussing lately is only possible if the class is public; everyone can access anything. This behaviour is undesirable because classes, as we have said, already have private data too.
Solution 🙂
Memento
So, what is a Memento? In literary terms, a memento is a reminder of an important event that has occurred in the past. Notes, photographs or anything tangible that helps recall a past event can be called memento(s).
The idea is pretty much identical in object-oriented designs, except that we deal with classes and objects. So, a memento is an object which stores the state of an object.
But why memento?
- Memento separates the saved state from the original object and helps maintain cohesion.
- Memento pattern delegates the responsibility of creating a snapshot to the original object. Since the object has full access to its data, it takes the encapsulation concern out of the equation.
- Memento exposes a limited interface to external entities, thus not compromising private fields.
- The original object has full access to memento data and uses it to restore its previous state.
So, the memento pattern addresses almost every issue identified above. Let’s explore the memento pattern more to understand the complete solution.
Anatomy of memento pattern
An Originator is an original object which creates snapshots. The originator creates snapshots and stores them in memento objects.

Caretaker objects are another set of classes that can store memento objects and interact with them via their limited interface. The purpose is usually to store them or dispatch commands on them without peeking inside them.

Benefits of the Memento Pattern
- Maintain original class cohesion by keeping the state in a memento.
- Creates a snapshot of the object without compromising data encapsulation.
- Exposes a simple interface for creating a copy of an object’s state.
Complete Architecture | Memento Pattern in PHP

Memento Pattern PHP Pseudocode Example
<?php
interface Originator {
public function createSnapshot();
}
// The originator class
class WhiteBoard implements Originator {
private $fontSize;
private $fontFamily;
private $canvasSize;
private $canvasColor;
private $output;
//More fields...
function __construct($fontSize, $fontFamily, $canvasSize, $canvasColor, $output) {
$this->fontSize = $fontSize;
$this->fontFamily = $fontFamily;
$this->canvasSize = $canvasSize;
$this->canvasColor = $canvasColor;
$this->output = $output;
}
function setFontSize($fontSize) {
$this->fontSize = $fontSize;
}
function setFontFamily($fontFamily) {
$this->fontFamily = $fontFamily;
}
function setCanvasSize($canvasSize) {
$this->canvasSize = $canvasSize;
}
function setCanvasColor($canvasColor) {
$this->canvasColor = $canvasColor;
}
function setOutput($output) {
$this->output = $output;
}
function getStateInfo() {
return "\nFont Size: ".$this->fontSize."\nFont Family: ".$this->fontFamily.
"\nCanvas Size: ".$this->canvasSize."\nCanvas Color: ".$this->canvasColor."\nOutput Format: ".$this->output."\n\n";
}
// Saves the state to the momento
function createSnapshot() {
//Passes reference to itself and fields.
return new SnapShot($this, $this->fontSize, $this->fontFamily, $this->canvasSize, $this->canvasColor, $this->output);
}
//More methods....
}
interface Memento {
public function restore();
}
// The memento class
class SnapShot implements Memento {
private $whiteboard;
private $fontSize;
private $fontFamily;
private $canvasSize;
private $canvasColor;
private $output;
function __construct($whiteboard, $fontSize, $fontFamily, $canvasSize, $canvasColor, $output) {
$this->whiteboard = $whiteboard;
$this->fontSize = $fontSize;
$this->fontFamily = $fontFamily;
$this->canvasSize = $canvasSize;
$this->canvasColor = $canvasColor;
$this->output = $output;
}
//Restores the originator state by passing the stored set of fields to the setter functions.
function restore() {
$this->whiteboard->setFontSize($this->fontSize);
$this->whiteboard->setFontFamily($this->fontFamily);
$this->whiteboard->setCanvasSize($this->canvasSize);
$this->whiteboard->setCanvasColor($this->canvasColor);
$this->whiteboard->setOutput($this->output);
}
}
//The UndoCommand act as a caretaker.
class UndoCommand {
private $memento;
function createSnapshot($whiteboard) {
$this->memento = $whiteboard->createSnapshot();
}
function undo() {
//If memento exists
if($this->memento) {
$this->memento->restore();
}
}
}
function main() {
$whiteboard = new Whiteboard('20px', 'Arial', '1000px', 'White', 'png');
$undoCommand = new UndoCommand();
echo "Initial State: ".$whiteboard->getStateInfo();
//Creates snapshot of the initial state
$undoCommand->createSnapshot($whiteboard);
//New state
$whiteboard->setFontSize('11px');
$whiteboard->setFontFamily('Times new roman');
$whiteboard->setCanvasSize('800px');
$whiteboard->setCanvasColor('Brown');
$whiteboard->setOutput('jpeg');
echo "New State: ".$whiteboard->getStateInfo();
//Reverts whiteboard to initial state
$undoCommand->undo();
echo "Reverted State: ".$whiteboard->getStateInfo();
}
/*
OUTPUT
Initial State:
Font Size: 20px
Font Family: Arial
Canvas Size: 1000px
Canvas Color: White
Output Format: png
New State:
Font Size: 11px
Font Family: Times new roman
Canvas Size: 800px
Canvas Color: Brown
Output Format: jpeg
Reverted State:
Font Size: 20px
Font Family: Arial
Canvas Size: 1000px
Canvas Color: White
Output Format: png
*/
?>
Pros and Cons of the Memento Pattern in PHP
Pros | Cons |
Satisfied single responsibility principle by keeping saved state separate from the original object. | Creating memento objects too often can consume a large chunk of memory. |
Doesn’t violate the data encapsulation of the original objects. | No easy way of marking and deleting obsolete memento objects. |
Provides an easy interface for creating snapshots. |
Where is the Memento Pattern Used
- To implement state retention and restoration in stateful components of a program.
- Text editors, IDEs and version controls can use the memento pattern.
What is the Memento Pattern
The memento pattern is a behavioral design pattern which lets you save and restore an object to its previous state without compromising its privacy.
Using the Memento Pattern in PHP Today
That’s all about the memento pattern. Let’s quickly sum up what we have learned thus far. The memento pattern is a behavioral design pattern which lets you save and restore an object to its previous state without compromising its privacy.
The memento pattern has three main components: Originator, which creates its state snapshot. Memento saves the state and helps restores it. The Caretaker stores the memento objects and uses their limited public interface for interaction.
This article features a whiteboard application with several options that represent its state. The goal is to create an undo function for it so that a user can revert to the previous state. One direct way is to loop through the object’s fields and copy them individually. Although this approach is easy, it has some flaws, including the issue that it compromises the data encapsulation of the original object.
That’s why we use the memento pattern, which delegates the snapshot creation to the originator object so that its data encapsulation is not violated. The memento saves the state to improve the cohesion of the originator class. The process of creating a snapshot thus becomes quite convenient with this pattern.
That’s all. See you in another design pattern article.
Books on Design Patterns
Want to learn more about Design Patterns? There are many great resources online. We recommend the following books for your collection as they both can teach you the theoretical and the application of using design patterns in your day-to-day programming. Feel free to use the following Amazon affiliate links if you’d like to purchase them and a way to support our efforts.
Design Patterns: Elements of Reusable Object-Oriented Software

This is the book that started it all. I believe that every programmer should have a referenced copy to this book at some point in their career. There have been many updates and excellent newer content through the years, but this is a classic. It still stands the test of time and is just as relevant for today as it was in the original printing in the 90s.
Learning PHP Design Patterns

This is an excellent book to go beyond the theory and apply it to writing good PHP code. Learning PHP Design Patterns is published by the popular O’Reilly media company. O’Reilly consistently publishes some of the most useful reference material related to software development. They are known to provide materials that thoroughly cover a topic in a way that is simple to understand. I recommend this book to every PHP developer.
Want to see our full review of books on design patterns? Read our huge review article on over 15 design pattern books.
Design Patterns in PHP Learning Series.
This article is part of our series of design patterns in PHP. We are going through all of the patterns and showing how they can help you build better applications. Browse through our full list of patterns below.
- What are Design Patterns in PHP?
- Books on Design Patterns
- Builder Design Pattern
- Strategy Design Pattern
- Factory Design Pattern
- Prototype Design Pattern
- Singleton Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Iterator Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Facade Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- State Design Pattern
- Observer Design Pattern
- Momento Design Pattern
- Mediator Design Pattner
- Chain of Responsibility Design Pattern