PHP Interpreter Design Pattern Behavioral Pattern

PHP Interpreter Pattern

A short screencast: the Interpreter pattern — a language grammar is expressed as a tree of objects, and every node can evaluate itself. We build the expression (5 + 3) * 2 and get 16.

Interpreter Pattern — open the lesson page

Overview

The Interpreter describes a language grammar with a set of classes and teaches every node of the tree to evaluate itself. A terminal node, Number, stores a ready value, while the non-terminal Add and Multiply hold two nested expressions and recursively ask them to compute. The client builds the tree (5 + 3) * 2 and calls interpret() only on the root — the evaluation then flows through the tree by itself. To add a new grammar rule it is enough to implement Expression with one more class.

UML diagram

classDiagram class Expression { <<interface>> +interpret(): int } class Number { -value: int +interpret(): int } class Add { -left: Expression -right: Expression +interpret(): int } class Multiply { -left: Expression -right: Expression +interpret(): int } Expression <|-- Number : implements Expression <|-- Add : implements Expression <|-- Multiply : implements Add o-- Expression : children Multiply o-- Expression : children

Code

Expression.php

interface Expression
{
    public function interpret(): int;
}

Number.php

class Number implements Expression
{
    public function __construct(private int $value) {}

    public function interpret(): int
    {
        return $this->value;
    }
}

Add.php

class Add implements Expression
{
    public function __construct(private Expression $left, private Expression $right) {}

    public function interpret(): int
    {
        return $this->left->interpret() + $this->right->interpret();
    }
}

Multiply.php

class Multiply implements Expression
{
    public function __construct(private Expression $left, private Expression $right) {}

    public function interpret(): int
    {
        return $this->left->interpret() * $this->right->interpret();
    }
}

demo.php

require_once 'Expression.php';
require_once 'Number.php';
require_once 'Add.php';
require_once 'Multiply.php';

$add = new Add(new Number(5), new Number(3));
$multiply = new Multiply($add, new Number(2));

echo $multiply->interpret().PHP_EOL;

Example output

After php demo.php the tree evaluates itself: the addition is nested inside the multiplication, and the root interpret() returns the result of (5 + 3) * 2:

16

Advantages

  • The grammar is described with explicit classes instead of ad-hoc string parsing.
  • A new grammar rule is just a new expression; existing code does not change.
  • Rules compose easily: any expression can be nested inside another.
  • Each node is responsible only for its own rule (single responsibility principle).

When to use

  • When there is a small language or notation to interpret: queries, conditions, formulas.
  • When the grammar is small and stable and its rules map neatly to classes.
  • When the same rule must be reused inside other expressions.
  • When evaluation naturally maps to a tree of objects with recursion.

Usage in Laravel

In Laravel the Interpreter shows up wherever a rule becomes an object with an evaluation method. The classic example is validation rules (Illuminate\Contracts\Validation\Rule and Illuminate\Validation\Rules\*): each rule encapsulates its own logic and can validate a value. The same approach is used by Illuminate\Database\Query\Expression and database rules, and by query filters, where a set of conditions is assembled as a tree and evaluated when the SQL is built.