Command Design Pattern in PHP: A Complete Guide

Command Design Pattern

The Command Design Pattern in PHP is a powerful behavioral pattern that turns requests into standalone objects. By encapsulating a request in an object, developers gain flexibility, reusability, and better separation of concerns. This pattern is especially useful when you want to queue operations, log actions, or implement undo/redo functionality in your application.

In PHP projects, the Command Design Pattern helps reduce tight coupling between classes. Instead of directly invoking methods, you delegate execution to command objects, making your code easier to extend and maintain. This design principle is a crucial part of writing clean and scalable PHP applications.

What is the Command Design Pattern in PHP?

The Command Design Pattern encapsulates an action and its parameters inside an object. It separates the invoker (the part that triggers the action) from the receiver (the part that actually performs the action).

Key Participants:

  • Command Interface – Declares the execution method.
  • Concrete Commands – Implement the command interface and define actions.
  • Receiver – Knows how to perform the actual work.
  • Invoker – Triggers the command without knowing its implementation.
  • Client – Configures commands and associates them with the invoker.

Bad Example: Without the Command Design Pattern

Here’s an example of tightly coupled PHP code that violates separation of concerns:

class Light {
    public function turnOn() {
        echo "Light is ON\n";
    }

    public function turnOff() {
        echo "Light is OFF\n";
    }
}

class SwitchController {
    private $light;

    public function __construct(Light $light) {
        $this->light = $light;
    }

    public function pressButton($action) {
        if ($action === "ON") {
            $this->light->turnOn();
        } elseif ($action === "OFF") {
            $this->light->turnOff();
        }
    }
}

$light = new Light();
$switch = new SwitchController($light);
$switch->pressButton("ON");
$switch->pressButton("OFF");

Problem: The SwitchController is tightly coupled to Light and requires condition checks for each action. Adding more actions makes the code harder to maintain.

Good Example: Command Design Pattern in PHP

By applying the Command Design Pattern, we decouple the invoker from the receiver and improve scalability.

// Command interface
interface Command {
    public function execute(): void;
}

// Receiver
class Light {
    public function turnOn() {
        echo "Light is ON\n";
    }

    public function turnOff() {
        echo "Light is OFF\n";
    }
}

// Concrete Commands
class TurnOnLightCommand implements Command {
    private $light;

    public function __construct(Light $light) {
        $this->light = $light;
    }

    public function execute(): void {
        $this->light->turnOn();
    }
}

class TurnOffLightCommand implements Command {
    private $light;

    public function __construct(Light $light) {
        $this->light = $light;
    }

    public function execute(): void {
        $this->light->turnOff();
    }
}

// Invoker
class RemoteControl {
    private $command;

    public function setCommand(Command $command) {
        $this->command = $command;
    }

    public function pressButton() {
        $this->command->execute();
    }
}

// Client
$light = new Light();

$onCommand = new TurnOnLightCommand($light);
$offCommand = new TurnOffLightCommand($light);

$remote = new RemoteControl();
$remote->setCommand($onCommand);
$remote->pressButton();

$remote->setCommand($offCommand);
$remote->pressButton();

Benefits:

  • Cleaner separation of responsibilities.
  • Adding new commands doesn’t affect existing code.
  • Enables undo/redo functionality.
  • Makes command queuing and logging possible.

When to Use the Command Design Pattern in PHP?

You should use the Command Design Pattern when:

  • You want to decouple invokers from receivers.
  • You need undo/redo functionality.
  • You want to support queuing and scheduling tasks.
  • You want a uniform way to trigger different operations.

Advantages of the Command Design Pattern

  • Loose Coupling – The invoker doesn’t need to know implementation details.
  • Scalability – Easily add new commands without modifying existing code.
  • Flexibility – Commands can be reused across different invokers.
  • Undo/Redo Support – Each command can define how to reverse its action.

Conclusion

The pattern in PHP is an elegant solution for managing requests as objects. It improves flexibility, reusability, and maintainability in applications where actions need to be queued, logged, or undone. By implementing this pattern, you can transform tightly coupled code into a cleaner and more scalable architecture.

Interested in More Design Patterns?

Discover other powerful patterns like Factory, Strategy, and Observer in this full guide:

➡️ Design Patterns in PHP – The Complete Guide to All Types