Design Patterns in PHP - Observer Pattern

So far in my series of articles on design patterns in PHP we’ve looked at a creational pattern, a structural pattern and a behavioral pattern. Today I’ll be taking a closer look at another behavioral pattern - the observer. The observer pattern (also known as the Subscribe/Publish Pattern) is used to notify one object, the observer, about a change of state from another object, the subject.
By Sam Holman
7th February 2011
The implementation of the observer pattern is a fairly simple one, as illustrated in the following UML class diagram (courtesy of Wikipedia):
UML Diagram
The implementation of this pattern relies on 2 base objects - the subject and one or more observer(s). The observers register themselves with the subject, who’s job is then to notify the observer on any change of state or progress.
In PHP we are lucky to have some predefined interfaces for this pattern in the SPL. Using the SplObserver and SplSubject interfaces we can quickly create an implementation of this pattern.
Let us suppose that we have a script which is performing a particular action on a list of users. We may or may not want to log the fact that this action has occurred - perhaps this is an option given to each user in the application. One way to achieve this notification is by using an observer object. In the example below a User_List is asked to update each User, and when it does it will notify any observers that the status has changed.
Users.inc.php
_users = $users;
        $this->_observers = array();
    }

    /**
     * Updates the users
     */
    public function updateUsers()
    {
        foreach ($this->_users as $user)
        {
            $this->_currentUser = $user;

            //Do update

            $this->notify();
        }
        $this->_currentUser = null;
    }

    /**
     * Returns the item currently being updated
     *
     * @return $user
     */
    public function getCurrent()
    {
        return $this->_currentUser;
    }

    /**
     * Attach an observer
     *
     * @param SplObserver $observer
     */
    public function attach(SplObserver $observer)
    {
        array_push($this->_observers, $observer);
    }

    /**
     * Detach an observer
     *
     * @param SplObserver $observer
     */
    public function detach(SplObserver $observer)
    {
        foreach ($this->_observers as $key => $item)
        {
            if ($observer == $item) {
                unset($this->_observers[$key]);
            }
        }
    }

    /**
     * Send notification to all observers
     */
    public function notify()
    {
        foreach ($this->_observers as $key => $item) {
            $item->update($this);
        }
    }
}
UserUpdateLogger.inc.php
getCurrent() . "\n";
    }
}
Controller.php
attach($logger);

$users->updateUsers();
The above example is fairly trivial so as to explain the point, but as you can see, the Users class could have multiple observers attached - perhaps one to log the output to a file or send an e-mail. The users class could also have no observers attached at all and would still function correctly.
In conclusion, the observer pattern can be used when there is a need to dynamically attach and detach objects which need to be notified of a certain action, without coupling any particular objects together too tightly.
As always, comments on twitter are welcome, @labelmedia.

Like this? Sign up to our newsletter for more!

Add your own comment

© 2014 Label Media
We are recruiting