The best way to allow the application to PHP

I started using PHP to create a new Web application, this time I want to create something that people can use to extend the plug-in interface.

How to write "hook" in the code, so that the plug can be attached to a particular event?

You can use the Observer pattern. A simple way to accomplish this function:

<?php

/** Plugin system **/

$listeners = array();

/* Create an entry point for plugins */
function hook() {
    global $listeners;

    $num_args = func_num_args();
    $args = func_get_args();

    if($num_args < 2)
        trigger_error("Insufficient arguments", E_USER_ERROR);

    // Hook name should always be first argument
    $hook_name = array_shift($args);

    if(!isset($listeners[$hook_name]))
        return; // No plugins have registered this hook

    foreach($listeners[$hook_name] as $func) {
        $args = $func($args); 
    }
    return $args;
}

/* Attach a function to a hook */
function add_listener($hook, $function_name) {
    global $listeners;
    $listeners[$hook][] = $function_name;
}

/////////////////////////

/** Sample Plugin **/
add_listener('a_b', 'my_plugin_func1');
add_listener('str', 'my_plugin_func2');

function my_plugin_func1($args) {
    return array(4, 5);
}

function my_plugin_func2($args) {
    return str_replace('sample', 'CRAZY', $args[0]);
}

/////////////////////////

/** Sample Application **/

$a = 1;
$b = 2;

list($a, $b) = hook('a_b', $a, $b);

$str  = "This is my sample applicationn";
$str .= "$a + $b = ".($a+$b)."n";
$str .= "$a * $b = ".($a*$b)."n";

$str = hook('str', $str);
echo $str;
?>

<Strong> Output:

This is my CRAZY application
4 + 5 = 9
4 * 5 = 20

** Note:

For this example source code, you must declare all plugins before the actual source code that you want to extend. I have included an example of how to handle the transfer of single or multiple values ​​to plug in. Which is the hardest part of writing the actual document, which lists the parameters passed to each hook.

This is just one way to complete plugin system in PHP. There are better options, I suggest you check WordPress documentation for more information.

Sorry, the underscore character is replaced Markdown to HTML entities? When this error is resolved, I can re-publish this code.

Edit: It does not matter, only when you edit _

When there is this assumption that you do not need the Observer pattern because it requires you to change your class methods to handle listening task and requires some general things. Suppose you do not want to use extendsinheritance because you may have inherited the other classes in your class. There is a common way to make any kind can effortlessly can it? This is how:

<?php

////////////////////
// PART 1
////////////////////

class Plugin {

    private $_RefObject;
    private $_Class = '';

    public function __construct(&$RefObject) {
        $this->_Class = get_class(&$RefObject);
        $this->_RefObject = $RefObject;
    }

    public function __set($sProperty,$mixed) {
        $sPlugin = $this->_Class . '_' . $sProperty . '_setEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }   
        $this->_RefObject->$sProperty = $mixed;
    }

    public function __get($sProperty) {
        $asItems = (array) $this->_RefObject;
        $mixed = $asItems[$sProperty];
        $sPlugin = $this->_Class . '_' . $sProperty . '_getEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }   
     大专栏  允许插入PHP应用程序的最佳方法    return $mixed;
    }

    public function __call($sMethod,$mixed) {
        $sPlugin = $this->_Class . '_' .  $sMethod . '_beforeEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }
        if ($mixed != 'BLOCK_EVENT') {
            call_user_func_array(array(&$this->_RefObject, $sMethod), $mixed);
            $sPlugin = $this->_Class . '_' . $sMethod . '_afterEvent';
            if (is_callable($sPlugin)) {
                call_user_func_array($sPlugin, $mixed);
            }       
        } 
    }

} //end class Plugin

class Pluggable extends Plugin {
} //end class Pluggable

////////////////////
// PART 2
////////////////////

class Dog {

    public $Name = '';

    public function bark(&$sHow) {
        echo "$sHow<br />n";
    }

    public function sayName() {
        echo "<br />nMy Name is: " . $this->Name . "<br />n";
    }


} //end class Dog

$Dog = new Dog();

////////////////////
// PART 3
////////////////////

$PDog = new Pluggable($Dog);

function Dog_bark_beforeEvent(&$mixed) {
    $mixed = 'Woof'; // Override saying 'meow' with 'Woof'
    //$mixed = 'BLOCK_EVENT'; // if you want to block the event
    return $mixed;
}

function Dog_bark_afterEvent(&$mixed) {
    echo $mixed; // show the override
}

function Dog_Name_setEvent(&$mixed) {
    $mixed = 'Coco'; // override 'Fido' with 'Coco'
    return $mixed;
}

function Dog_Name_getEvent(&$mixed) {
    $mixed = 'Different'; // override 'Coco' with 'Different'
    return $mixed;
}

////////////////////
// PART 4
////////////////////

$PDog->Name = 'Fido';
$PDog->Bark('meow');
$PDog->SayName();
echo 'My New Name is: ' . $PDog->Name;

In Part 1, you might use the top of the PHP script require_once()calling contain them. It loads class to create pluggable class.

In Part 2, which is where we loaded the class. Please note that I do not have to do anything special for the course, which the observer pattern is significantly different.

In Part 3, we switch to the class "pluggable" (i.e., let us support widget classes covering methods and properties). So, for example, if you have a web application, you might have a plug-in registry, you can activate the plugin here. Also note that Dog_bark_beforeEvent()function. If I set before the return statement $ mixed ='BLOCK_EVENT', it will stop barking will stop Dog_bark_afterEvent, because there will be no incidents.

In Part 4, which is the normal operation code, but please note that you may think that running code would not run. For example, the dog did not announce its name is 'Fido', but 'Coco'. Dogs do not say 'meow', but 'Woof'. And when you want to see the dog's name, you will find that it is 'different' rather than 'cocoa'. All of these rewrites are provided in Part 3.

So how does this work? So, let's rule out eval()(everyone says "evil"), and it is not excluded Observer pattern. Therefore, it works Pluggable cavity is known class, it does not contain attributes and methods Dog class. So, since it occurs, will do magic for us. This is why in Part 3 and Part 4, we confuse derived from the Pluggable class object, not the Dog class itself. Instead, we let the Plugin class for us to do a "touch" Dog object.
(If this is some kind of design patterns, I do not know - please let me know.)

Without the consent of the author, this is forbidden and offenders accountable!

Guess you like

Origin www.cnblogs.com/sanxiandoupi/p/11724395.html