0
0
PHPprogramming~5 mins

Observer pattern in PHP

Choose your learning style9 modes available
Introduction

The Observer pattern helps objects talk to each other when something changes. It makes sure many parts can update automatically without being tightly connected.

You want to update multiple parts of a program when one part changes, like updating a display when data changes.
You want to keep parts of your program loosely connected so changes in one place don't break others.
You want to send notifications to many objects when an event happens, like sending alerts to users.
You want to separate the logic of what happens when data changes from the data itself.
Syntax
PHP
<?php
interface Observer {
    public function update(string $message): void;
}

interface Subject {
    public function attach(Observer $observer): void;
    public function detach(Observer $observer): void;
    public function notify(): void;
}

class ConcreteSubject implements Subject {
    private array $observers = [];
    private string $state = '';

    public function attach(Observer $observer): void {
        $this->observers[] = $observer;
    }

    public function detach(Observer $observer): void {
        $this->observers = array_filter(
            $this->observers,
            fn($obs) => $obs !== $observer
        );
    }

    public function notify(): void {
        foreach ($this->observers as $observer) {
            $observer->update($this->state);
        }
    }

    public function setState(string $state): void {
        $this->state = $state;
        $this->notify();
    }
}

class ConcreteObserver implements Observer {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    public function update(string $message): void {
        echo "Observer {$this->name} received update: {$message}\n";
    }
}
?>

The Subject keeps a list of Observer objects and notifies them when needed.

Observers implement an update method to receive messages or data changes.

Examples
This example shows how to create a subject and two observers. When the subject state changes, both observers get notified.
PHP
<?php
// Create subject and observers
$subject = new ConcreteSubject();
$observer1 = new ConcreteObserver('A');
$observer2 = new ConcreteObserver('B');

// Attach observers
$subject->attach($observer1);
$subject->attach($observer2);

// Change state and notify observers
$subject->setState('Hello Observers!');
?>
Here, one observer is removed. Only the remaining observer receives the update.
PHP
<?php
// Detach an observer
$subject->detach($observer1);

// Change state again
$subject->setState('Second update');
?>
Sample Program

This program shows the Observer pattern in action. Two observers listen to the subject. When the subject changes, both get notified. Then one observer is removed, and only the remaining observer gets the next update.

PHP
<?php
interface Observer {
    public function update(string $message): void;
}

interface Subject {
    public function attach(Observer $observer): void;
    public function detach(Observer $observer): void;
    public function notify(): void;
}

class ConcreteSubject implements Subject {
    private array $observers = [];
    private string $state = '';

    public function attach(Observer $observer): void {
        $this->observers[] = $observer;
    }

    public function detach(Observer $observer): void {
        $this->observers = array_filter(
            $this->observers,
            fn($obs) => $obs !== $observer
        );
    }

    public function notify(): void {
        foreach ($this->observers as $observer) {
            $observer->update($this->state);
        }
    }

    public function setState(string $state): void {
        $this->state = $state;
        $this->notify();
    }
}

class ConcreteObserver implements Observer {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    public function update(string $message): void {
        echo "Observer {$this->name} received update: {$message}\n";
    }
}

// Create subject and observers
$subject = new ConcreteSubject();
$observer1 = new ConcreteObserver('A');
$observer2 = new ConcreteObserver('B');

// Attach observers
$subject->attach($observer1);
$subject->attach($observer2);

// Change state and notify observers
$subject->setState('Hello Observers!');

// Detach one observer
$subject->detach($observer1);

// Change state again
$subject->setState('Second update');
?>
OutputSuccess
Important Notes

Make sure to detach observers when they no longer need updates to avoid memory leaks.

The pattern helps keep code organized and easy to change.

Summary

The Observer pattern lets objects watch and react to changes in another object.

It helps keep parts of your program loosely connected and easy to update.

Use it when many things need to know about changes in one place.