Direkt zum Inhalt | Direkt zur Navigation

Benutzerspezifische Werkzeuge
Anmelden
Home Produkte

SaaS

Software as a Service

Hosting

schon ab €14,00!

Software-Entwicklung

Wir programmieren alles, was wir hosten.

Lösungen

Web & E-Commerce

Kollaboration

Hosting & Skalierbarkeit

Support Open Source

Python

PHP

Weitere

Über uns

Kontakt

Wir

Sie sind hier: Startseite Open Source PHP Subscriber.php Subscriber.php - Sourcecode und Dokumentation

Subscriber.php - Sourcecode und Dokumentation

<?php
/*
 * File: Subscriber.php
 *
 * Copyright (c) 2007 by Daniel Kraft <dk@d9t.de>
 *
 * GNU General Public License (GPL)
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * If you find bugs, please feel free to report them by mail or on
 * irc: freenode://#d9t
 *
 *
 * Subscriber Pattern
 * ==================
 *
 * This is the subscriber-pattern implemented in php4 (and php5 if you're willing to
 * accept the wrong documentation and use __construct instead of the class-name as
 * constructor). It's not clean, but it will probarbly work.
 * Usage:
 *
 * Define your events:
 *
 * >>> class MyEvent {
 * ...     // This is just a event with a piece of data.
 * ...     var $a;
 * ...     function MyEvent($a) {
 * ...         $this->a = $a;
 * ...     }
 * ... }
 * ... class AnotherEvent {
 * ...     // Whew - just another event!
 * ... }
 *
 * Then define your subscribers. This can either be a globaly defined function or a class,
 * which should derive from Subscriber.
 * A function takes the event as argument.
 * A class must implement the __call__ method, which takes the event as argument.
 * __call__ will be called upon notification.
 *
 * Function use-case:
 * 
 * >>> function doSomething($event) {
 * ...     print "I'm doing something ".$event->a."\n";
 * ... }
 *
 * Class use-case:
 * 
 * >>> class DoSomethingClass extends Subscriber {
 * ...     function DoSomething($var1, $var2) {
 * ...         // initialize whatever
 * ...     }
 * ...
 * ...     function __call__($event) {
 * ...         // This is actually called upon notification.
 * ...         print "Hey, I'm a fully functional object!\n";
 * ...     }
 * ... }
 * 
 * Now you may subscribe to your event:
 *
 * >>> subscribe(MyEvent, doSomething);
 * >>> subscribe(MyEvent, new DoSomething(1,2));
 *
 * We can also subscribe to other events.
 *
 * >>> subscribe(AnotherEvent, new DoSomething(4,5));
 *
 * Then, at some time, we simply notify the event.
 * 
 * >>> notify(new MyEvent(44));
 * I'm doing something 44
 * Hey, I'm a fully functional object!
 *
 * >>> notify(AnotherEvent);
 * Hey, I'm a fully functional object!
 * 
 * Please take care to pass existing instances by reference, or you will copy the state of the object
 * due to php's difficulties with references:
 *
 * >>> class CounterEvent {
 * ...     $increment = 1;
 * ...     function CounterEvent($increment=1) {
 * ...         $this->increment = $increment;
 * ...     }
 * ... }
 * >>> class Counter extends Subscriber {
 * ...     var $i=0;
 * ...     function __call__($event) {
 * ...         $this->i += $event->increment;
 * ...         print "Called ".$this->i." times\n";
 * ...     }
 * ... }
 * 
 * >>> $counter = new Counter();
 * >>> subscribe(CounterEvent, &$counter);	// see the "&"?
 * >>> notify(new CounterEvent());
 * Called 1 times
 * 
 * >>> notify(new CounterEvent());
 * Called 2 times
 *
 * >>> notify(new CounterEvent(3));
 * Called 5 times
 *
 * TODO:
 * - unsubscription
 * - get list of subscribers
 * - obscure the global variable somehow so that namespace collision is less likely
 *
*/

function subscribe($event, $obj) {
    /*
     * This method subscribes the obj to an event.
     */
    // php4 uses SMALL klass names. WHY?!
    if (version_compare(phpversion(), '5.0.0', '<') == 1)
        $event = strtolower($event);
    if (!is_array($GLOBALS["_subscribers"])) $GLOBALS["_subscribers"] = array();
    if (!is_array($GLOBALS["_subscribers"][$event])) $GLOBALS["_subscribers"][$event] = array();
    $GLOBALS["_subscribers"][$event][] =& $obj;
}

function notify($event) {
    /*
     * This notifies an event, i.e. calls all subscribers.
     * Per specification this calls functions with the event as argument and
     * classes' __call__ method also with event as argument.
     */
    $klass = get_class($event);

    if (!is_array($GLOBALS["_subscribers"])) return;
    if (!is_array($GLOBALS["_subscribers"][$klass])) return;
    for ($i=0; $i<count($GLOBALS["_subscribers"][$klass]); $i++) {
        $subscriber =& $GLOBALS["_subscribers"][$klass][$i];
        // call instance
        if (method_exists($subscriber, '__call__'))
            $subscriber->__call__($event);
        // call function
        else
            $subscriber($event);
    }
}

class Subscriber {
    function __call__($event) {
        // Implement whatever you need here.
    }
}


?>