PHP外掛系統的實現(六):完整經理類

VeryCool發表於2021-06-15
<?php

class PluginManager{
    /**
     * 已經上班的員工/已經啟用的外掛:用來監聽or監控
     * @access private
     * @var array
     */
    private $_staff = [];
    /**
     * 建構函式
     *
     * @access public
     * @return void
     */
    public function __construct(){
        $this->detector();
    }
    /** 
    * 初始化所有外掛類 

    * @access public 
    * @return void
    */
    public function detector(){
        //主要功能為將外掛需要執行功能放入  $_staff
        $plugins  =  $this->get_active_plugins();

        if($plugins){
            foreach($plugins as $plugin){
                #這裡將所有外掛踐行初始化
                #路徑請自己注意
                if (@file_exists($plugin['path'])){
                    include_once($plugin['path']);
                    #此時設定 資料夾名稱 檔名稱 類名 是統一的 如果想設定不統一請自己在get_active_plugins()內進行實現
                    $class =  $plugin['name'];
                    if (class_exists($class)){
                        #初始化所有外掛類
                        new  $class($this);
                    }
                }
            }
        }
    }

     /**
      * 這裡是在外掛中使用的方法 用來註冊外掛
      *
      * @param string $hook
      * @param object $class_name
      * @param string $method
      */
    public function register($hook, &$class_name, $method)
    {
        #獲取類名和方法名連結起來做下標
        $func_class = get_class($class_name).'->'.$method;
        #將類和方法放入監聽陣列中 以$func_class做下標
        $this->_staff[$hook][$func_class] = array(&$class_name, $method);

    }

    /**
     * 這個是全域性使用的觸發鉤子動作方法
     *
     * @param string $hook
     * @param string $data
     * @return string
     */
    public function trigger($hook, $data='')
    {
        #首先需要判斷一下$hook 存不存在

        if (isset($this->_staff[$hook]) && is_array($this->_staff[$hook]) && count($this->_staff[$hook]) > 0) {
            $plugin_func_result = '';
            #如果存在定義 $plugin_func_result
            foreach ($this->_staff[$hook] as $staff)
            {
                # 如果只是記錄 請不要返回
                $plugin_func_result = '';
                $class = &$staff[0]; #引用過來的類
                $method = $staff[1]; #類下面的方法
                if(method_exists($class,$method))
                {
                    $func_result = $class->$method($data);
                    if(is_numeric($func_result)){
                        #這裡判斷返回值是不是字串,如果不是將不進行返回到頁面上
                        $plugin_func_result .= $func_result;
                    }

                }
            }
        }

        return $plugin_func_result ?? '';
    }

    /**
     * 獲取外掛資訊
     */
    public function get_active_plugins(){
        # 既假定了外掛在根目錄的/plugin
        # 我們再次假定外掛的入口和外掛資料夾的名字是一樣的
        # 既假定了外掛在根目錄的/plugin
        # 注意:這個執行檔案我放在了根目錄 以下路徑請根據實際情況獲取

        $plugin_dir_path = '.'.DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR;

        $plugin_dir_name_arr = scandir($plugin_dir_path);

        $plugins = array();
        foreach($plugin_dir_name_arr as $k=>$v){
            if($v=="." || $v==".."){continue;}
            if(is_dir($plugin_dir_path.$v)){
                $path = $plugin_dir_path.$v.DIRECTORY_SEPARATOR.$v.'.php';
                $plugins[] = ['name'=>$v,'path'=>$path];
            }

        }
        return $plugins;
    }


}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章