PHP Observer pattern using PHP SPL Library
see PHP SPL Library
/** * Login is observable */ class Login implements SplSubject { private $_observers; private $_status; function __construct() { $this->_observers = new SplObjectStorage(); } function attach(SplObserver $obs) { // requires that observers must be of type LoginObserver to be attached if (is_a($obs, "LoginObserver")) { $this->_observers->attach($obs); } else { throw new Exception("Only 'LoginObservers' can be attached to the Subject/Observable 'Login'"); } } function detach(SplObserver $obs) { $this->_observers->detach($obs); } // function to notify observers something has changed function notify() { foreach ($this->_observers as $obs) { $obs->update($this); } } function login() { echo "Logging in ... "; $this->_status = rand(1,2); $this->notify(); // trigger notification broadcast } function getStatus() { return $this->_status; } } abstract class LoginObserver implements SplObserver { function update(SplSubject $sub) { // requires that subject must be of type Login // ensures that function getStatus() exists if (is_a($sub, "Login")) { $this->doUpdate($sub); } else { throw new Exception("Subject must be od type 'Login'"); } } abstract function doUpdate(Login $login); } class LoginLogger extends LoginObserver { function doUpdate(Login $login) { echo " - Logging status: " . $login->getStatus() . " "; } } class FailedLoginLogger extends LoginObserver { function doUpdate(Login $login) { if ($login->getStatus() == 2) { echo " - Logging FAILED login: " . $login->getStatus() . " "; } } } class NewObserver implements SplObserver { function update(SplSubject $sub) { echo " * From 'NewObserver' ... "; } } $login = new Login(); $login->attach(new LoginLogger()); $login->attach(new FailedLoginLogger()); $login->attach(new NewObserver()); // error !!! unless the line checking Observers to be of type LoginObserver is removed for ($i = 0; $i < 10; $i++) { $login->login(); }
Outputs ...
Logging in ... - Logging status: 1 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 1 Logging in ... - Logging status: 1 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 1














