How is SplSubject/SplObserver useful?
observer-pattern, php, spl
Solution
You can implement the update method with an optional parameter and still satisfy the SplSubject interface.
class MyObserver implements SplObserver {
public function update(SplSubject $subject, $eventData = null) {
if (is_null($eventData))
// carefull
}
}
Problem
The Standard PHP Library includes what some resources call a reference implementation of the Observer pattern, by way of the `SplSubject` and `SplObserver` classes. For the life of me, I can't figure out how these are very useful with no way to pass actual events or any other information along with the notifications: ``` class MySubject implements SplSubject { protected $_observers = []; public function attach(SplObserver $observer) { $id = spl_object_hash($observer); $this->_observers[$id] = $observer; } public function detach(SplObserver $observer) { $id = spl_object_hash($observer); if (isset($this->_observers[$id])) { unset($this->_observers[$id]); } } public function notify() { foreach ($this->_observers as $observer) { $observer->update($this); } } } class MyObserver implements SplObserver { public function update(SplSubject $subject) { // something happened with $subject, but what // was it??? } } $subject = new MySubject(); $observer = new MyObserver(); $subject->attach($observer); $subject->notify(); ``` It seems like these interfaces are pretty much useless for any real world problem. Can someone enlighten me? Edit: Here's my biggest problem with the interface (although there are others): ``` public function update(SplSubject $subject, Event $event) { /* ... */ } ``` ...nets the following fatal error: ``` PHP Fatal error: Declaration of MyObserver::update() must be compatible with SplObserver::update(SplSubject $SplSubject) ``` Edit #2: Making the additional parameters optional by giving them defaults prevents the fatal error and provides a way to pass context, making implementations worthwhile. I wasn't previously aware of this, so this pretty much answers my question. The solution is to pass your own event/message data, and check for its existance inside `SplObserver::update()`.