PHP Command Design Pattern Behavioral Pattern

PHP Command Pattern

A short screencast: the Command pattern — turn a request into an object. The remote stores a command and invokes it without knowing what will happen: the light turns on or off.

Command Pattern — open the lesson page

Overview

A command turns a request into a separate object with an execute method. The client creates a command and hands it to the invoker — the remote. The remote stores the command and, when the button is pressed, simply calls execute, knowing neither the light nor what will actually happen. The command itself holds a reference to the receiver — the light — and decides which of its methods to call. The request thus becomes a standalone object: it can be stored, passed around and swapped.

UML diagram

classDiagram class Command { <<interface>> +execute(): string } class Light { +on(): string +off(): string } class LightOnCommand { -light: Light +execute(): string } class LightOffCommand { -light: Light +execute(): string } class RemoteControl { -command: Command +setCommand(command: Command) +pressButton(): string } Command <|-- LightOnCommand : implements Command <|-- LightOffCommand : implements LightOnCommand o-- Light : receiver LightOffCommand o-- Light : receiver RemoteControl o-- Command : invokes

Code

Command.php

interface Command
{
    public function execute(): string;
}

Light.php

class Light
{
    public function on(): string
    {
        return 'Light is on';
    }

    public function off(): string
    {
        return 'Light is off';
    }
}

LightOnCommand.php

class LightOnCommand implements Command
{
    public function __construct(private Light $light) {}

    public function execute(): string
    {
        return $this->light->on();
    }
}

LightOffCommand.php

class LightOffCommand implements Command
{
    public function __construct(private Light $light) {}

    public function execute(): string
    {
        return $this->light->off();
    }
}

RemoteControl.php

class RemoteControl
{
    private ?Command $command = null;

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

    public function pressButton(): ?string
    {
        return $this->command?->execute();
    }
}

demo.php

require_once 'Command.php';
require_once 'Light.php';
require_once 'LightOnCommand.php';
require_once 'LightOffCommand.php';
require_once 'RemoteControl.php';

$light = new Light;
$remote = new RemoteControl;

$remote->setCommand(new LightOnCommand($light));
echo $remote->pressButton().PHP_EOL;

$remote->setCommand(new LightOffCommand($light));
echo $remote->pressButton().PHP_EOL;

Example output

Running php demo.php makes the remote invoke two commands in turn, turning the light on and off:

Light is on
Light is off

Advantages

  • Turns a request into an object: a command can be stored, passed around and logged.
  • The invoker knows neither the receiver nor the operation itself.
  • New commands are added without touching the remote or the client.
  • Makes queues, undo and redo straightforward to implement.

When to use

  • When an object must be parameterised with an action.
  • When requests should be queued, logged or undone.
  • When the invoker and the receiver must not know about each other.
  • When the same operation is triggered from several places.

Usage in Laravel

In Laravel a command is a queued job: a class under app/Jobs/* implements handle(), and dispatch() puts it on a queue from which a worker invokes it without knowing the details. The same idea applies to the Artisan command class (Illuminate\Console\Command) with its handle() method and to the Illuminate\Bus\Dispatcher, which routes a command to its handler.