Best way to allow plugins for a PHP application

前端 未结 8 657
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-27 09:12

I am starting a new web application in PHP and this time around I want to create something that people can extend by using a plugin interface.

How does one go about

相关标签:
8条回答
  • 2020-11-27 09:44

    The hook and listener method is the most commonly used, but there are other things you can do. Depending on the size of your app, and who your going to allow see the code (is this going to be a FOSS script, or something in house) will influence greatly how you want to allow plugins.

    kdeloach has a nice example, but his implementation and hook function is a little unsafe. I would ask for you to give more information of the nature of php app your writing, And how you see plugins fitting in.

    +1 to kdeloach from me.

    0 讨论(0)
  • 2020-11-27 09:44

    Here is an approach I've used, it's an attempt to copy from Qt signals/slots mechanism, a kind of Observer pattern. Objects can emit signals. Every signal has an ID in the system - it's composed by sender's id + object name Every signal can be binded to the receivers, which simply is a "callable" You use a bus class to pass the signals to anybody interested in receiving them When something happens, you "send" a signal. Below is and example implementation

        <?php
    
    class SignalsHandler {
    
    
        /**
         * hash of senders/signals to slots
         *
         * @var array
         */
        private static $connections = array();
    
    
        /**
         * current sender
         *
         * @var class|object
         */
        private static $sender;
    
    
        /**
         * connects an object/signal with a slot
         *
         * @param class|object $sender
         * @param string $signal
         * @param callable $slot
         */
        public static function connect($sender, $signal, $slot) {
            if (is_object($sender)) {
                self::$connections[spl_object_hash($sender)][$signal][] = $slot;
            }
            else {
                self::$connections[md5($sender)][$signal][] = $slot;
            }
        }
    
    
        /**
         * sends a signal, so all connected slots are called
         *
         * @param class|object $sender
         * @param string $signal
         * @param array $params
         */
        public static function signal($sender, $signal, $params = array()) {
            self::$sender = $sender;
            if (is_object($sender)) {
                if ( ! isset(self::$connections[spl_object_hash($sender)][$signal])) {
                    return;
                }
                foreach (self::$connections[spl_object_hash($sender)][$signal] as $slot) {
                    call_user_func_array($slot, (array)$params);
                }
    
            }
            else {
                if ( ! isset(self::$connections[md5($sender)][$signal])) {
                    return;
                }
                foreach (self::$connections[md5($sender)][$signal] as $slot) {
                    call_user_func_array($slot, (array)$params);
                }
            }
    
            self::$sender = null;
        }
    
    
        /**
         * returns a current signal sender
         *
         * @return class|object
         */
        public static function sender() {
            return self::$sender;
        }
    
    }   
    
    class User {
    
        public function login() {
            /**
             * try to login
             */
            if ( ! $logged ) {
                SignalsHandler::signal(this, 'loginFailed', 'login failed - username not valid' );
            }
        }
    
    }
    
    class App {
        public static function onFailedLogin($message) {
            print $message;
        }
    }
    
    
    $user = new User();
    SignalsHandler::connect($user, 'loginFailed', array($Log, 'writeLog'));
    SignalsHandler::connect($user, 'loginFailed', array('App', 'onFailedLogin'));
    
    $user->login();
    
    ?>
    
    0 讨论(0)
提交回复
热议问题