Using the Command Pattern in PHP
The command pattern is a behavioral design pattern that encapsulates a request into an object (command) that knows all about the receiving entity of this request. It allows you to parameterize objects with different requests, schedules or log requests and supports undoable operations.
Article Highlights
- The command pattern decouples the invoker of action from the receiver by encapsulating the request for action as a separate object (command object).
- Benefit â You can separate one application layer from another and use command objects to allow communications between the two.
- Con â The code becomes complicated with all the new command classes in the application
Command Design Pattern PHP Code Example
<?php
interface Command {
public function execute();
}
class LightOnCommand implements Command {
private $light; //Expects reference to the Light object
public function __construct($light) {
$this->light = $light;
}
public function execute() {
$this->light->switchOn();
}
}
class LightOffCommand implements Command {
private $light; //Expects reference to the Light object
public function __construct($light) {
$this->light = $light;
}
public function execute() {
$this->light->switchOff();
}
}
class MicOnCommand implements Command {
private $mic; //Expects reference to the Mic object
public function __construct($mic) {
$this->mic = $mic;
}
public function execute() {
$this->mic->switchOn();
}
}
class MicOffCommand implements Command {
private $mic; //Expects reference to the Mic object
public function __construct($mic) {
$this->mic = $mic;
}
public function execute() {
$this->mic->switchOff();
}
}
class ACOnCommand implements Command {
private $ac; //Expects reference to the Airconditioner object
public function __construct($ac) {
$this->ac = $ac;
}
public function execute() {
$this->ac->switchOn();
}
}
class ACOffCommand implements Command {
private $ac; //Expects reference to the Airconditioner object
public function __construct($ac) {
$this->ac = $ac;
}
public function execute() {
$this->ac->switchOff();
}
}
class CameraOnCommand implements Command {
private $camera; //Expects reference to the Camera object
public function __construct($camera) {
$this->camera = $camera;
}
public function execute() {
$this->camera->switchOn();
}
}
class CameraOffCommand implements Command {
private $camera; //Expects reference to the Camera object
public function __construct($camera) {
$this->camera = $camera;
}
public function execute() {
$this->camera->switchOff();
}
}
class SpeakerOnCommand implements Command {
private $speaker; //Expects reference to the Speaker object
public function __construct($speaker) {
$this->speaker = $speaker;
}
public function execute() {
$this->speaker->switchOn();
}
}
class SpeakerOffCommand implements Command {
private $speaker; //Expects reference to the Speaker object
public function __construct($speaker) {
$this->speaker = $speaker;
}
public function execute() {
$this->speaker->switchOff();
}
}
class PanelOnCommand implements Command {
private $panel; //Expects reference to the Speaker object
public function __construct($panel) {
$this->panel = $panel;
}
public function execute() {
$this->panel->switchOn();
}
}
class PanelOffCommand implements Command {
private $panel; //Expects reference to the Speaker object
public function __construct($panel) {
$this->panel = $panel;
}
public function execute() {
$this->panel->switchOff();
}
}
/*
Receiver object which has the implementation for performing an action
*/
class Light {
public function switchOn() {
echo "Light is switched on\n";
}
public function switchff() {
echo "Light is switched off\n";
}
/*
Other methods
*/
}
class Mic {
public function switchOn() {
echo "Mic is switched on\n";
}
public function switchff() {
echo "Mic is switched off\n";
}
/*
Other methods
*/
}
class AirConditioner {
public function switchOn() {
echo "Airconditioner is switched on\n";
}
public function switchff() {
echo "Airconditioner is switched off\n";
}
/*
Other methods
*/
}
class Camera {
public function switchOn() {
echo "Camera is switched on\n";
}
public function switchff() {
echo "Camera is switched off\n";
}
/*
Other methods
*/
}
class Speaker {
public function switchOn() {
echo "Speaker is switched on\n";
}
public function switchff() {
echo "Speaker is switched off\n";
}
/*
Other methods
*/
}
class Panel {
public function switchOn() {
echo "Panel is switched on\n";
}
public function switchff() {
echo "Panel is switched off\n";
}
/*
Other methods
*/
}
/*
Invoker object has a reference to the command object
and would pass on request to it.
*/
class Button {
private $buttonID;
private $command; //Expects a command object
public function __construct($buttonID, $command) {
$this->buttonID = $buttonID;
$this->command = $command;
}
public function setCommand($command) {
$this->command = $command;
}
public function executeCommand() {
$this->command->execute();
}
public function getButtonID() {
return $this->buttonID;
}
}
class Dashboard {
private $buttons;
public function __construct($buttons) {
$this->buttons = [];
foreach($buttons as $v) {
$this->buttons[$v->getButtonID()] = $v; //Associate array with buttonIDs as keys.
}
}
public function buttonClicked($ID) {
$this->buttons[$ID]->executeCommand();
}
}
function bootstrapDashboard() {
/*
Receivers
*/
$light = new Light();
$mic = new Mic();
$ac = new AirConditioner();
$camera = new Camera();
$speaker = new Speaker();
$panel = new Panel();
/*
Commands
*/
$lightOnCommand = new LightOnCommand($light);
$lightOffCommand = new LightOffCommand($light);
$micOnCommand = new MicOnCommand($mic);
$micOffCommand = new MicOffCommand($mic);
$acOnCommand = new ACOnCommand($ac);
$acOffCommand = new ACOffCommand($ac);
$speakerOnCommand = new SpeakerOnCommand($speaker);
$speakerOffCommand = new SpeakerOffCommand($speaker);
$panelOnCommand = new PanelOnCommand($panel);
$panelOffCommand = new PanelOffCommand($panel);
/*
Invokers
*/
$buttons = [
new Button('1', $lightOnCommand ),
new Button('2', $lightOffCommand ),
new Button('3', $micOnCommand ),
new Button('4', $micOffCommand ),
new Button('5', $acOnCommand ),
new Button('6', $acOffCommand ),
new Button('7', $speakerOnCommand ),
new Button('8', $speakerOffCommand ),
new Button('9', $panelOnCommand ),
new Button('10', $panelOffCommand )
];
return new Dashboard($buttons);
}
function run() {
$dashboard = bootstrapDashboard();
$dashboard->buttonClicked('1');
$dashboard->buttonClicked('3');
$dashboard->buttonClicked('5');
$dashboard->buttonClicked('7');
$dashboard->buttonClicked('9');
}
/*
OUTPUT
Light is switched on
Mic is switched on
Airconditioner is switched on
Speaker is switched on
Panel is switched on
*/
?>

Table of Contents
- What is Command Pattern?
- Example of Command Pattern
- Problem Scenario
- Solution
- Benefits of Command Design Pattern
- Complete Architecture of Command Pattern
- Pseudocode of Command Pattern
- Pros & Cons of Command Pattern
- Use cases of Command Pattern
- Conclusion
What is the Command Pattern
âThe command pattern is a behavioral design pattern that encapsulates a request into an object (command) that knows all about the receiving entity of this request. It allows you to parameterize objects with different requests, schedules or log requests and supports undoable operations.â

Command Pattern Example
A university wants software for its central auditorium that will help automate the manual switch controls of the electronic components installed throughout the auditorium. They already have hardware APIs for these components and want us to use them.

They want us to create software with all the control buttons stacked in columns in a dashboard. Users should be able to switch components by clicking the buttons on this dashboard.

The hardware APIs are pretty versatile, with no standard interface. Also, it is highly likely to see more components in the future. Should we bind these concrete classes to the dashboard buttons? Is that an excellent idea?Â
Though the dashboard will work as expected, the design has many shortcomings.
Problem đ
Single responsibility principle
âA class should have one and only one responsibility.â, states the single responsibility principle. A class in which a set of methods based around a similar context or aspect is said to have high cohesion. For example, a class Downloader has to have methods to support video download functionality only and a Converter to support video convert functionality. Mixing up both these in one class is generally a bad idea.
Classes with high cohesion are focused and specialized; hence, any change happening outside their domain has the least or no effect on them. Contrary to that, changing a system with low cohesion is not less than a migraine for developers because the change may propagate farther than its radius.
In the dashboard, we have elements like buttons, columns, a container, and a layout to arrange them in the container. All these visual elements fall in the presentational layer. Anything related to the component function falls in the logical, implementational, or business layers.Â
The proposed solution wonât mind the distinctions between these two layers and merge them all into one. Consequently, we will have code with cluttered and less cohesive modules with little or no flexibility.
Open/closed principle
âA class should be closed for modification but open for extension.â, states the open/closed principle. When a class uses concrete objects of another class, introducing new types of objects is often difficult because that usually means changing the existing system.
Contrary to this, programming to abstractions leads to more flexible designs where we can add objects without breaking the existing code. When different objects follow one common interface, we can leverage the power of polymorphism to refer to them by their abstraction.
Our solution doesnât care much about this principle and hardcodes the logic in the presentational layer. This implementation is a huge miss in terms of maintainability and flexibility. Users wonât be able to customize the dashboard because buttons use concrete classes. Also, any change to the hardware API could break the dashboard software.Â
Lack of abstraction
We donât have abstraction in the current design. The dashboard refers to concrete hardware API objects with no common interface in between. A lack of abstraction in a system is a red flag when assessing a software design.
It wonât be wrong to call lack of abstraction the root cause of non-flexible and non-maintainable software. Program to interface, not implementation, is key to remember if we want to create software for today and tomorrow.
Solution đ
Separation of concerns
The dashboard and its elements are purely visual. They donât have to worry about the gnarly implementation details of any hardware API object. In other words, we should define a presentational and implementational layer to separate the concerns.

The buttons should have a function solely responsible for delegating the action to another object. That way, the UI will act more independently as a layer and pass the request to another entity. With that architecture, the software modules will be loosely coupled, and the dashboard can be much more reusable and extendable.
Invoker & receiver
Continuing along the same line, we can call the dashboard the âInvokerâ because the dashboard is the origin of a request for action or call to action. Action means some operation on the hardware.
The hardware API objects are the âReceiversâ as they communicate and perform actions on the hardware. The invoker initiates a request for action which a receiver receives and fulfills. That sounds like the old proposed system with the invoker and receivers interacting directly.
Something missing could help us create that abstraction and layered architecture by sitting between the invoker and receivers.
Introducing command objects
A command object will be an intermediary between the two layers. It will receive the request from the invoker and forward it to the appropriate object by calling the action function on it. Every command object will have a reference to an API object and will call the appropriate action method on it.
These command objects implement a standard interface Command
.
interface Command {
public function execute();
}
For example, the LightOnCommand object will refer to a Light object and will call the switchOn() on it when the invoker requests it. Consequently, we have command objects for every action on every component.
class LightOnCommand implements Command {
private $light; //Expects reference to the Light object
public function __construct($light) {
$this->light = $light;
}
public function execute() {
$this->light->switchOn();
}
}
/*
Receiver object which has the implementation for performing an action
*/
class Light {
public function switchOn() {
echo "Light is switched on\n";
}
public function switchff() {
echo "Light is switched off\n";
}
/*
Other methods
*/
}
The invoker will call execute() on the LightOnCommand object, which in turn would call the switchOn() on the Light object.

A Button object acts as an invoker since it initiates the request on a click event.
/*
Invoker object has a reference to the command object
and would pass on request to it.
*/
class Button {
private $buttonID;
private $command; //Expects a command object
public function __construct($buttonID, $command) {
$this->buttonID = $buttonID;
$this->command = $command;
}
public function setCommand($command) {
$this->command = $command;
}
public function executeCommand() {
$this->command->execute();
}
public function getButtonID() {
return $this->buttonID;
}
}
Since we have an invoker, command, and receiver object, we are ready for a quick test run.
function run() {
$light = new Light(); //Receiver
$lightOnCommand = new LightOnCommand($light); //Command
$lightOnButton = new Button('1', $lightOnCommand ); //Invoker
$lightOnButton->executeCommand();
}
//Output
//Light is switched on
Awesome! The pseudocode includes a complete example. We have commands for switch operations only. All other actions and their commands will follow the same pattern. If you understand the command pattern, implementing them wonât be a hard code to crack.
Benefits of the Command Pattern
- Decouples invoker from the receiver object by passing requests to the command object.
- It is possible to parameterize the command object, chain them with other commands, or switch them at runtime.
- Could implement undo, scheduling, and logging operations via command objects.
Complete Architecture | Command Pattern in PHP

Command Pattern PHP Pseudocode Example
<?php
interface Command {
public function execute();
}
class LightOnCommand implements Command {
private $light; //Expects reference to the Light object
public function __construct($light) {
$this->light = $light;
}
public function execute() {
$this->light->switchOn();
}
}
class LightOffCommand implements Command {
private $light; //Expects reference to the Light object
public function __construct($light) {
$this->light = $light;
}
public function execute() {
$this->light->switchOff();
}
}
class MicOnCommand implements Command {
private $mic; //Expects reference to the Mic object
public function __construct($mic) {
$this->mic = $mic;
}
public function execute() {
$this->mic->switchOn();
}
}
class MicOffCommand implements Command {
private $mic; //Expects reference to the Mic object
public function __construct($mic) {
$this->mic = $mic;
}
public function execute() {
$this->mic->switchOff();
}
}
class ACOnCommand implements Command {
private $ac; //Expects reference to the Airconditioner object
public function __construct($ac) {
$this->ac = $ac;
}
public function execute() {
$this->ac->switchOn();
}
}
class ACOffCommand implements Command {
private $ac; //Expects reference to the Airconditioner object
public function __construct($ac) {
$this->ac = $ac;
}
public function execute() {
$this->ac->switchOff();
}
}
class CameraOnCommand implements Command {
private $camera; //Expects reference to the Camera object
public function __construct($camera) {
$this->camera = $camera;
}
public function execute() {
$this->camera->switchOn();
}
}
class CameraOffCommand implements Command {
private $camera; //Expects reference to the Camera object
public function __construct($camera) {
$this->camera = $camera;
}
public function execute() {
$this->camera->switchOff();
}
}
class SpeakerOnCommand implements Command {
private $speaker; //Expects reference to the Speaker object
public function __construct($speaker) {
$this->speaker = $speaker;
}
public function execute() {
$this->speaker->switchOn();
}
}
class SpeakerOffCommand implements Command {
private $speaker; //Expects reference to the Speaker object
public function __construct($speaker) {
$this->speaker = $speaker;
}
public function execute() {
$this->speaker->switchOff();
}
}
class PanelOnCommand implements Command {
private $panel; //Expects reference to the Speaker object
public function __construct($panel) {
$this->panel = $panel;
}
public function execute() {
$this->panel->switchOn();
}
}
class PanelOffCommand implements Command {
private $panel; //Expects reference to the Speaker object
public function __construct($panel) {
$this->panel = $panel;
}
public function execute() {
$this->panel->switchOff();
}
}
/*
Receiver object which has the implementation for performing an action
*/
class Light {
public function switchOn() {
echo "Light is switched on\n";
}
public function switchff() {
echo "Light is switched off\n";
}
/*
Other methods
*/
}
class Mic {
public function switchOn() {
echo "Mic is switched on\n";
}
public function switchff() {
echo "Mic is switched off\n";
}
/*
Other methods
*/
}
class AirConditioner {
public function switchOn() {
echo "Airconditioner is switched on\n";
}
public function switchff() {
echo "Airconditioner is switched off\n";
}
/*
Other methods
*/
}
class Camera {
public function switchOn() {
echo "Camera is switched on\n";
}
public function switchff() {
echo "Camera is switched off\n";
}
/*
Other methods
*/
}
class Speaker {
public function switchOn() {
echo "Speaker is switched on\n";
}
public function switchff() {
echo "Speaker is switched off\n";
}
/*
Other methods
*/
}
class Panel {
public function switchOn() {
echo "Panel is switched on\n";
}
public function switchff() {
echo "Panel is switched off\n";
}
/*
Other methods
*/
}
/*
Invoker object has a reference to the command object
and would pass on request to it.
*/
class Button {
private $buttonID;
private $command; //Expects a command object
public function __construct($buttonID, $command) {
$this->buttonID = $buttonID;
$this->command = $command;
}
public function setCommand($command) {
$this->command = $command;
}
public function executeCommand() {
$this->command->execute();
}
public function getButtonID() {
return $this->buttonID;
}
}
class Dashboard {
private $buttons;
public function __construct($buttons) {
$this->buttons = [];
foreach($buttons as $v) {
$this->buttons[$v->getButtonID()] = $v; //Associate array with buttonIDs as keys.
}
}
public function buttonClicked($ID) {
$this->buttons[$ID]->executeCommand();
}
}
function bootstrapDashboard() {
/*
Receivers
*/
$light = new Light();
$mic = new Mic();
$ac = new AirConditioner();
$camera = new Camera();
$speaker = new Speaker();
$panel = new Panel();
/*
Commands
*/
$lightOnCommand = new LightOnCommand($light);
$lightOffCommand = new LightOffCommand($light);
$micOnCommand = new MicOnCommand($mic);
$micOffCommand = new MicOffCommand($mic);
$acOnCommand = new ACOnCommand($ac);
$acOffCommand = new ACOffCommand($ac);
$speakerOnCommand = new SpeakerOnCommand($speaker);
$speakerOffCommand = new SpeakerOffCommand($speaker);
$panelOnCommand = new PanelOnCommand($panel);
$panelOffCommand = new PanelOffCommand($panel);
/*
Invokers
*/
$buttons = [
new Button('1', $lightOnCommand ),
new Button('2', $lightOffCommand ),
new Button('3', $micOnCommand ),
new Button('4', $micOffCommand ),
new Button('5', $acOnCommand ),
new Button('6', $acOffCommand ),
new Button('7', $speakerOnCommand ),
new Button('8', $speakerOffCommand ),
new Button('9', $panelOnCommand ),
new Button('10', $panelOffCommand )
];
return new Dashboard($buttons);
}
function run() {
$dashboard = bootstrapDashboard();
$dashboard->buttonClicked('1');
$dashboard->buttonClicked('3');
$dashboard->buttonClicked('5');
$dashboard->buttonClicked('7');
$dashboard->buttonClicked('9');
}
/*
OUTPUT
Light is switched on
Mic is switched on
Airconditioner is switched on
Speaker is switched on
Panel is switched on
*/
?>
Pros and Cons of the Command Pattern in PHP
Pros | Cons |
Satisfies the single responsibility principle as we have classes focused on doing one kind of a job. | The code becomes complicated with all the new command classes in the application. |
Satisfies the open/closed principle because we can add as many commands and receivers without affecting the existing code. | |
You can separate one application layer from another and use command objects to allow communications between the two. | |
You can have macro commands that execute multiple commands in one invocation. |
Where is the Command Pattern Used
- Graphical user interfaces use command objects to bind UI elements and event-based actions.
- Schedulers, job queues, thread pools, and timers can use command objects to implement job and thread scheduling.
- Logging and transactional application where we can store command objects and roll back or redo operations using them.
What is the Command pattern?
The command pattern is a behavioral design pattern that encapsulates a request into an object (command) that knows all about the receiving entity of this request. It allows you to parameterize objects with different requests, schedules or log requests and supports undoable operations.
Using the Command Pattern in PHP Today
Voila! Thatâs all about the command pattern. Letâs have an overview of what we have seen in this article. The command pattern is a behavioral design pattern that encapsulates a request into an object (command) that knows all about the receiving entity of this request. It allows you to parameterize objects with different requests, schedules or log requests and supports undoable operations.
The command pattern decouples the invoker from the receiver of the action by introducing command objects. The command object encapsulates the request and knows the receiver that is supposed to fulfill the request. The article features dashboard software for automating electronic components in a university auditorium.
Developers devise a solution where the invoker (dashboard buttons) directly calls methods on the receiver object. The design has many shortcomings in terms of design, and due to a lack of abstraction, it lacks the flexibility to support any future instances of receivers.
The design also overlooks fundamental design principles. Thus the developers rethink a solution where they could add a layer of abstraction between the two communicating entities, and therefore they program the command interface.
The invoker calls the common execute() method on the command objects regardless of their concrete type and leaves the rest to the command object. The command objects encapsulate a receiver object and call methods on it. Such a design allows for layering our application into presentational and implementation layers and letting the command objects bind the two.
The application modules are then more cohesive and flexible because we can add as many receiver objects and commands without affecting the existing codebase.
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