← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Observer Pattern

general PHP 5.0+ Intermediate

Also Known As

observer event listener pattern pub-sub pattern

TL;DR

Defines a one-to-many dependency so that when one object changes state, all its registered observers are notified automatically.

Explanation

The Observer (or Event/Listener) pattern decouples the subject (event emitter) from its observers (listeners). Observers register interest with the subject; when the subject's state changes, it notifies all registered observers without knowing their concrete types. In PHP frameworks, this is implemented as event dispatchers (Symfony EventDispatcher, Laravel Events). It is ideal for cross-cutting concerns like logging, cache invalidation, and email notifications that shouldn't pollute domain logic. Avoid overuse — complex event chains are hard to trace and debug.

Common Misconception

Observer pattern and event bus are equivalent. Observer creates direct registration between subject and observer objects. An event bus decouples them completely — publishers and subscribers do not reference each other at all, communicating only through the bus.

Why It Matters

The Observer pattern decouples event producers from consumers — an object fires an event without knowing who is listening, enabling new behaviours to be added by registering new observers.

Common Mistakes

  • Not removing observers when they are no longer needed — memory leaks in long-running processes.
  • Observers that throw exceptions crashing the event dispatch loop — catch inside the observer or the dispatcher.
  • Synchronous observers performing slow operations (email, HTTP calls) — use async dispatch for heavy work.
  • Circular event chains where an observer triggers an event that re-triggers the same observer.

Avoid When

  • The event chain is hard to follow — deeply nested observers triggering other observers cause debugging nightmares.
  • Observers are synchronous and slow — a single slow listener blocks all subsequent listeners and the original caller.
  • The order of observer execution matters and is not guaranteed — use an ordered pipeline instead.
  • You only have one listener — a direct method call is simpler and equally clear.

When To Use

  • Decoupling a publisher from multiple independent consumers that react to the same event.
  • Plugin or extension systems where third-party code needs to hook into core events.
  • Audit logging, cache invalidation, and notifications that should not be in the core business logic.
  • UI frameworks and event-driven architectures where components react to state changes.

Code Examples

✗ Vulnerable
// Direct method calls — tight coupling:
class OrderService {
    public function place(Order $o): void {
        $this->save($o);
        $this->emailService->sendConfirmation($o); // Coupled
        $this->inventoryService->reserve($o);       // Coupled
        $this->analyticsService->track($o);         // Coupled
    }
}
// Better: dispatch OrderPlaced event; each service subscribes independently
✓ Fixed
interface EventListener {
    public function handle(object $event): void;
}

class EventDispatcher {
    private array $listeners = [];

    public function listen(string $event, EventListener $listener): void {
        $this->listeners[$event][] = $listener;
    }
    public function dispatch(object $event): void {
        foreach ($this->listeners[$event::class] ?? [] as $listener) {
            $listener->handle($event);
        }
    }
}

// Usage
$dispatcher->listen(OrderPlaced::class, new SendConfirmationEmail());
$dispatcher->listen(OrderPlaced::class, new UpdateInventory());
$dispatcher->dispatch(new OrderPlaced($order));

Added 15 Mar 2026
Edited 25 Mar 2026
Views 30
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 2 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 2 pings T
Amazonbot 1 Perplexity 1
No pings yesterday
Amazonbot 9 Perplexity 8 SEMrush 3 Unknown AI 2 Majestic 1 Google 1
crawler 24
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
Define a Subject interface with attach/detach/notify and an Observer interface with update — inject observers rather than hardcoding them in the subject
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Class directly calling methods on multiple other classes after state change instead of publishing an event
Auto-detectable: ✗ No phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class Tests: Update

✓ schema.org compliant