The Memento Design Pattern in PHP is a behavioral design pattern that allows you to capture and restore an object’s internal state without violating encapsulation. If you are building undo functionality, version history, or rollback mechanisms, understanding the Memento Design Pattern in PHP will dramatically improve your architecture. This pattern keeps your objects clean while still giving you the flexibility to restore previous states safely.
In this guide, you will learn how the pattern works, when to use it, and how to implement it using native PHP only.
What is the Memento Design Pattern?
The Memento Design Pattern is a behavioral pattern that stores an object’s internal state so it can be restored later. The key idea is:
- The object creates a snapshot of itself.
- The snapshot is stored externally.
- The object can restore itself from that snapshot.
This is commonly used in:
- Undo/Redo systems
- Text editors
- Game state saves
- Transaction rollbacks
Participants of the Pattern
- Originator – The object whose state needs to be saved.
- Memento – Stores the internal state.
- Caretaker – Manages the saved states.
Problem Without Memento Design Pattern
Let’s first look at a bad implementation where state management breaks encapsulation.
class Editor
{
public $content;
public function setContent(string $content): void
{
$this->content = $content;
}
}
$editor = new Editor();
$editor->setContent("Version 1");
// Manually storing state outside
$savedState = $editor->content;
$editor->setContent("Version 2");
// Restoring
$editor->content = $savedState;
Why This Is Bad?
- Public property exposes internal state.
- No control over state integrity.
- Breaks encapsulation.
- Hard to maintain in large applications.
This approach becomes dangerous in real-world applications where objects have complex dependencies.
Proper Implementation of Memento Design Pattern
Now let’s implement it properly using native PHP.
First Step: Create the Memento
class EditorMemento
{
private string $content;
public function __construct(string $content)
{
$this->content = $content;
}
public function getContent(): string
{
return $this->content;
}
}
Second Step: Create the Originator
class Editor
{
private string $content = '';
public function setContent(string $content): void
{
$this->content = $content;
}
public function getContent(): string
{
return $this->content;
}
public function save(): EditorMemento
{
return new EditorMemento($this->content);
}
public function restore(EditorMemento $memento): void
{
$this->content = $memento->getContent();
}
}
Third Step: Create the Caretaker
class History
{
private array $mementos = [];
public function push(EditorMemento $memento): void
{
$this->mementos[] = $memento;
}
public function pop(): ?EditorMemento
{
return array_pop($this->mementos);
}
}
Last Step: Using the Memento Design Pattern
$editor = new Editor();
$history = new History();
$editor->setContent("Version 1");
$history->push($editor->save());
$editor->setContent("Version 2");
$history->push($editor->save());
$editor->setContent("Version 3");
echo $editor->getContent(); // Version 3
$editor->restore($history->pop());
echo $editor->getContent(); // Version 2
$editor->restore($history->pop());
echo $editor->getContent(); // Version 1
Why Memento Design Pattern Matters
The Memento Design Pattern in PHP ensures that object state management remains clean and secure. Instead of exposing internal variables, the object itself controls how its state is saved and restored. This protects data integrity and enforces encapsulation.
In large PHP applications such as CMS systems, e-commerce platforms, or enterprise-level APIs, state restoration is common. For example, imagine building a custom WordPress page builder or form editor. Users constantly modify layouts, change content, or experiment with configurations. Without a structured undo mechanism, you risk corrupting data or implementing fragile workarounds. The Memento pattern allows you to build a controlled snapshot system where each change can be reversed safely without exposing internal properties.
Additionally, this pattern improves testability. You can easily simulate state transitions in unit tests by saving and restoring object states. This leads to predictable behavior and better debugging.
Another hidden benefit is separation of concerns. The Caretaker does not modify the object; it only stores snapshots. The Originator does not manage history; it only creates snapshots. This clear responsibility separation makes your code easier to extend and maintain.
When to Use Memento Design Pattern
Use it when:
- You need undo/redo functionality.
- You want to preserve encapsulation.
- You must store object history safely.
- You want clean separation between state management and business logic.
Avoid it when:
- The object state is extremely large.
- Performance is critical and memory is limited.
Advanced Insight: Optimizing Memento in Large Applications
If your object contains large datasets, storing full snapshots may consume memory. In such cases:
- Store only changed properties.
- Use serialization carefully.
- Implement a limit on stored history.
- Use immutable value objects internally.
For example, instead of saving the entire object, you could store only modified attributes inside the Memento.
This keeps your application scalable and memory-efficient.
Conclusion
The Memento Design Pattern is essential when implementing safe state restoration mechanisms. It protects encapsulation, keeps your code clean, and enables structured undo functionality without exposing internal data.
When applied correctly, this pattern significantly improves maintainability and architecture quality. It is especially powerful in content editors, configuration systems, workflow engines, and any system where state changes frequently.
Mastering behavioral patterns like this will elevate your PHP architecture skills and help you build scalable, maintainable systems using pure native PHP.
Interested in More Design Patterns?
Discover other powerful patterns like Factory, Strategy, and Observer in this full guide: