HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Listener/Observer Model in PHP

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
observerphpmodellistener

Problem

I've taken a look at the SPL Listener/Observer model but found that it doesn't work when using static methods. So I wrote my own but it's very simply. Can anyone suggest ways to make it more like the Model standards and if there is anything obvious that I've missed?

 $key, 'callback' => $callback);
    }

    public static function detach($event, $key, $callback){
        unset(static::$listeners[$event][md5($event.$key)]);
    }

    public static function listeners($event = ''){
        return ($event == '') ? static::$listeners : static::$listeners[$event];
    }

    public static function listenersRegistered(){
        return static::$listeners;
    }

    public static function listenersTriggered(){
        return static::$triggered;
    }

    public static function getBroadcasts(){
        return static::$broadcasts;
    }

    public static function broadcast($event){
        $rendered = \modular\core\Renderer::rendered();

        $caller = debug_backtrace();//true, 1 - check version and implement this
        array_shift($caller);

        static::$broadcasts[$event][] = $caller;

        if(isset(static::$listeners[$event])){
            if(!$rendered)
                ob_start();

            foreach(static::$listeners[$event] as $listener){
                $myEvent = (\modular\core\Router::routed() ? ($listener['module'] == \modular\core\ModuleLoader::getActiveModule()) : true);
                if($myEvent){
                    static::$triggered[$event] = $listener;
                    $test = \modular\core\ModuleLoader::runModule($listener);
                }
            }

            if(!$rendered)
                ob_end_clean();
        }
    }
}
?>


The code to add a listener:

```
public static function addListener($event, $callback){
$modules = \modular\core\ModuleLoader::getModules();

if(($key = array_search($callback[0], $modules)) !== false){
\modular\core\Listeners::attach($event, $key, $callback);

Solution

Because it's a framework static methods are used as my preferred method to access a class from multiple classes without having to worry about creating variables of instances that I either have to remember globally or re-instantiating the class constantly.

I don't do php, but I'll give this one a try.

Being a framework shouldn't be a reason to prefer static methods everywhere.

The Observer Pattern can be depicted as follows:


I've taken a look at the SPL Listener/Observer model but found that it doesn't work when using static methods.

There's a reason for that. If I read the code correctly, then when you have a class called SubjectA, and register 3 observers statically, every single instance of SubjectA will have the 3 observers registered; this is unlikely to be the intended behavior (not to mention threading issues), and it's only happening because of the static stuff.1

It looks like your Listeners class is intended to be used in object composition, like, you'll create a Car class that has a Listeners instance, and you'll register listeners for an Explode event. Then you might have a Dog class that has a[nother] Listeners instance, and you'll register listeners for a Bark event. If I assessed the situation correctly, that will give you a barking Car and an exploding Dog, on top of the expected events.

1 that is, if static in php has the same meaning as static in c#, which I'm assuming here.

Context

StackExchange Code Review Q#44591, answer score: 8

Revisions (0)

No revisions yet.