I am trying to create a CMS-like system in PHP. making it as modular and extendable as possible.
Could someone offer me the best-practice scenario of creating a event-listener system in PHP (a very simplified version of Drupal system for example), creating hooks and implementing them in a short example would also be nice.
Well, there's really three different ways of doing this from an implementation perspective (note that these are OO design patterns, but you could implement them functionally or procedurally if you wanted to).
1. Observer Pattern
You can implement the Observer Pattern. Basically, you'd have each thing that can raise events be a subject. Then the classes/code you want to listen binds to what it wants to listen to specifically. So let's say you have a controller called Foo
. If you wanted to listen to it, you could call $fooController->attach($observer);
. Then, whenever the controller wanted to say something, it would dispatch the event to all of the observers.
This is really well suited for a notification system (to extend what classes are doing). It's not as well suited for modifying the behavior of code in real time.
2. Decorator Pattern You can also implement the Decorator Pattern. Basically, you take the object that you want to modify, and "wrap" it in a new object that does what you want to change. This is really well suited for modifying and extending the behavior (since you can selectively override functionality from the wrapped class).
This works very well if you have defined interfaces and expect objects to conform to them. If you don't have interfaces (or don't use them properly), most of what the decorator pattern can do for you will be lost.
Also note that this really isn't a way of doing events, it's a way of modifying object behavior.
3. Mediator Pattern
You could also use a Mediator. Basically, you'd have one global mediator that keeps track of your listeners. When you want to trigger an event, you send the event to the mediator. The mediator can then keep track of which listening objects want to receive that event, and pass the message along properly.
This has the advantage of being central. Meaning multiple senders can send the same event, and to the listeners it doesn't make a difference who sent it...