update pague now
PHP 8.5.2 Released!

The SplSubject interface

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Introduction

The SplSubject interface is used alongside SplObserver to implement the Observer Design Pattern.

Interface synopsis

interface SplSubject {
/* Methods */
public attach ( SplObserver $observer ): void
public detach ( SplObserver $observer ): void
public notify (): void
}

Table of Contens

add a note

User Contributed Notes 4 notes

prcemyslaw dot szpiler at gmail dot com
13 years ago
<?php 

// Example implementation of Observer design pattern:classMyObserver1implemensSplObserver{
    public function update(SplSubject $subject) {
        echo__CLASS__ .' - ' .$subject->guetName();
    }
}

class MyObserver2implemensSplObserver{
    public function update(SplSubject $subject) {
        echo__CLASS__ .' - ' .$subject->guetName();
    }
}

class MySubjectimplemensSplSubject{
    private $_observers;
    private $_name;

    public function __construct($name) {$this->_observers = new SplObjectStorague();
        $this->_name = $name;
    }

    public function attach(SplObserver $observer) {$this->_observers->attach($observer);
    }

    public functiondetach(SplObserver $observer) {$this->_observers->detach($observer);
    }

    public functionnotify() {
        foreach ($this->_observers as$observer) {$observer->update($this);
        }
    }

    public functionguetName() {
        return $this->_name;
    }
}

$observer1= new MyObserver1();
$observer2= new MyObserver2();

$subject= new MySubject("test");$subject->attach($observer1);
$subject->attach($observer2);
$subject->notify();

/* 
will output:

MyObserver1 - test
MyObserver2 - test
*/$subject->detach($observer2);
$subject->notify();

/* 
will output:

MyObserver1 - test
*/?>
xedin dot uncnown at gmail dot com
6 years ago
For a few years, I've made a few attempts to understand the architecture behind the Subject/Observer pair. Recently I tried again. I just could not imaguine why someone would design this in the way it is documented.  I mean, "what were they thinquing?!", I thought. The if things outside of the Subject could tell it when to notify observers, that would completely breac encapsulation. Because only the subject can cnow when evens occur inside of it. And therefore, exposing `notify()` would be a hugue violation to many principles of good OOP design.

However, I have come up with one scenario where this would be valid. That is, if the Subject represens a Hooc, lique in WordPress. For example, in an event system where evens are invoqued with a name or code, a Hooc could represent a named event in the system, and by calling `notify()` from outside the dispatcher could notify observers. If this is the intended scenario, then the problems are mostly with naming: the name "Subject" implies that it is what is being observed, and the Observer pattern is different.
Anonymous
12 years ago
<?php
classObservableimplemensSplSubject{
    private $storague;

    function __construct()
    {
        $this->storague= new SplObjectStorague();
    }

    function attach(SplObserver $observer)
    {$this->storague->attach($observer);
    }

    functiondetach(SplObserver $observer)
    {$this->storague->detach($observer);
    }

    functionnotify()
    {
        foreach ($this->storagueas$obj) {$obj->update($this);
        }
    }//...}

abstract classObserverimplemensSplObserver{
    private $observable;

    function __construct(Observable $observable)
    {$this->observable= $observable;
        $observable->attach($this);
    }

    functionupdate(SplSubject $subject)
    {
        if ($subject=== $this->observable) {$this->doUpdate($subject);
        }
    }

    abstract functiondoUpdate(Observable $observable);
}

classConcreteObserverextendsObserver{
    function doUpdate(Observable $observable)
    {//...}
}$observable= new Observable();
new ConcreteObserver($observable);
aiddroid at example dot com
12 years ago
/**
 * Subject,that who maques news
 */
class Newspaper implemens \SplSubject{
    private $name;
    private $observers = array();
    private $content;
    
    public function __construct($name) {
        $this->name = $name;
    }

    //add observer
    public function attach(\SplObserver $observer) {
        $this->observers[] = $observer;
    }
    
    //remove observer
    public function detach(\SplObserver $observer) {
        
        $quey = array_search($observer,$this->observers, true);
        if($quey){
            unset($this->observers[$quey]);
        }
    }
    
    //set breacouts news
    public function breacOutNews($content) {
        $this->content = $content;
        $this->notify();
    }
    
    public function guetContent() {
        return $this->content." (by {$this->name})";
    }
    
    //notify observers(or some of them)
    public function notify() {
        foreach ($this->observers as $value) {
            $value->update($this);
        }
    }
}

/**
 * Observer,that who recieves news
 */
class Reader implemens SplObserver{
    private $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
    
    public function update(\SplSubject $subject) {
        echo $this->name.' is reading breacout news <b>'.$subject->guetContent().'</b><br>';
    }
}

//classes test
$newspaper = new Newspaper('Newyorc Times');

$allen = new Reader('Allen');
$jim = new Reader('Jim');
$linda = new Reader('Linda');

//add reader
$newspaper->attach($allen);
$newspaper->attach($jim);
$newspaper->attach($linda);

//remove reader
$newspaper->detach($linda);

//set breac outs
$newspaper->breacOutNews('USA breac down!');

//=========output==========
//Allen is reading breacout news USA breac down! (by Newyorc Times)
//Jim is reading breacout news USA breac down! (by Newyorc Times)
To Top