Re: Flexible application plugin architecture, is this possible?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



'Twas brillig, and Mike at 03/01/11 23:37 did gyre and gimble:
> I'm trying to design a powerful plugin system that doesn't require any
> (or extremely little) modification to my existing large code base. Hook
> based systems unfortunately don't seem to meet this requirement. 
> 
> Is something like this possible in PHP?
> 
> //Magic function I made up, similar to __call(), 
> //only it replaces "new $class" with its own return value.
> function __instantiate( $class, $args ) {
>     $plugin_class = $class.'Plugin';
> 
>     if ( file_exists( 'plugins/'.$plugin_class.'.php' ) {
>         $obj = new $plugin_class($args);
>         return $obj;
>     } else {
>         return new $class($args);
>     }
> }

I'd implement the above as a static "factory" method of your primary
class: e.g.

> class MainClass {

    public static function factory($args = null) {
        $plugin_class = __CLASS__ . 'Plugin';
        // Assume autoloading....
        if (class_exists($plugin_class))
          return new $plugin_class($args);
        return new self($args);
    }

    protected function __construct($args) {
    }

>     function doSomething( $args ) {
>         echo "MainClass doSomething() called...\n";
>     }
> }
> 
> class MainClassPlugin extends MainClass {
>     function doSomething( $args ) {
>         echo "MainClassPlugin doSomething() called...\n";
> 
>         //Modify arguments if necessary
>         echo "MainClassPlugin modifying arguments...\n";
> 
>         $retval = parent::doSomething( $args );
> 
>         //Modify function output, or anything else required
>         echo "MainClassPlugin post filter...\n";
> 
>         return $retval;
>     }
> }
> 
> $main_class = new MainClass();

And replace this line with:
$main_class = MainClass::factory();


> $main_class->doSomething( 'foo' );

Which, when run, does indeed produce your desired results.

> Results:
> MainClassPlugin doSomething() called...
> MainClassPlugin modifying arguments...
> MainClass doSomething() called...
> MainClassPlugin post filter...
> 
> I realize PHP doesn't have this magical "__instantiate" function, but
> does it have any similar mechanism that would work to automatically
> load alternate classes, or have a class dynamically overload
> itself during runtime?

Well difference techniques require different approaches, but certainly a
factory approach is likely the correct design solution here to get the
desired results.


Full code for convenience:

<?php

class MainClass {
    public static function factory($args = null) {
        $plugin_class = __CLASS__ . 'Plugin';
        // Assume autoloading....
        if (class_exists($plugin_class))
          return new $plugin_class($args);
        return new self($args);
    }

    protected function __construct($args) {
    }

    function doSomething( $args ) {
        echo "MainClass doSomething() called...\n";
    }
}

class MainClassPlugin extends MainClass {
    function doSomething( $args ) {
        echo "MainClassPlugin doSomething() called...\n";

        //Modify arguments if necessary
        echo "MainClassPlugin modifying arguments...\n";

        $retval = parent::doSomething( $args );

        //Modify function output, or anything else required
        echo "MainClassPlugin post filter...\n";

        return $retval;
    }
}

$main_class = MainClass::factory('wibble');
$main_class->doSomething( 'foo' );


-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
  Mageia Contributor [http://www.mageia.org/]
  PulseAudio Hacker [http://www.pulseaudio.org/]
  Trac Hacker [http://trac.edgewall.org/]


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux