多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 引用类库 ``` use think\Hook; use think\Loader; use think\Config; ``` ## 定义插件目录 ``` define('ADDON_PATH', ROOT_PATH . 'addons' . DS); // DS是/ ``` ## 注册类的根命名空间 ``` Loader::addNamespace('addons', ADDON_PATH); ``` ## 如果插件目录不存在则创建 ``` if(!is_dir(ADDON_PATH)){ @mkdir(ADDON_PATH, 0777, true); } ``` > mkdir(path,mode,recursive) > 如果成功该函数返回 TRUE,如果失败则返回 FALSE。 > 参数一:path必需。规定要创建的目录的名称。 > 参数二:mode可选。规定权限。默认是 0777(允许全局访问)。 > 参数三:recursive可选。规定是否设置递归模式。(PHP 5 中新增的) ## 处理插件钩子 ``` /** * 处理插件钩子 * @param [string] $hook [钩子名称] * @param array $params [传入参数] * @return [void] */ function hook($hook, $params=[]){ Hook::listen($hook, $params); //监听标签(钩子)的行为 } ``` > 函数功能:监听某个钩子,该钩子上挂载某个插件 ## 自动加载钩子的配置 > 文件名:composer.json > 代码: ``` { "name": "cmsaddons/think-addons", "description": "The ThinkPHP5 Addons Package", "license": "Apache-2.0", "authors": [ { "name": "lyc", "email": "lyc@studyfox.cn" } ], "autoload": { "psr-4": { "think\\": "src" }, "files": [ "src/common.php" ] } } ``` > PSR是PHP Standards Recommendation的简称,制定的代码规范,简称PSR,是代码开发的事实标准。 > PSR-4使代码更加规范,能够满足面向package的自动加载,它规范了如何从文件路径自动加载类,同时规范了自动加载文件的位置。 ## autoload\_psr4.php ``` <?php // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'think\\testing\\' => array($vendorDir . '/topthink/think-testing/src'), 'think\\helper\\' => array($vendorDir . '/topthink/think-helper/src'), 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'), 'think\\' => array($vendorDir . '/cmsaddons/think-addons/src'), ); ``` ## autoload\_files.php ``` <?php // autoload_files.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', '72c97b53391125cae04082a81029f42d' => $vendorDir . '/topthink/think-testing/src/config.php', 'ddc3cd2a04224f9638c5d0de6a69c7e1' => $vendorDir . '/cmsaddons/think-addons/src/common.php', ); ``` ## 插件挂载到钩子上 ``` Hook::add('',''); //两个参数,钩子名,插件名 ``` ## TP系统内置钩子 ``` app_init 应用初始化标签位 app_begin 应用开始标签位 module_init 模块初始化标签位 action_begin 控制器开始标签位 view_filter 视图输出过滤标签位 app_end 应用结束标签位 response_end 输出结束标签位(V5.0.1+) log_write 日志write方法标签位 ``` ## 初始化行为,系统内置钩子 ``` Hook::add('action_begin',function(){ $data = cache('hooks'); if(empty($data)){ //首页获取配置中的插件 $addons = (array)Config::get('addons'); // 初始化钩子 foreach ($addons as $key => $value) { if(is_string($value)){ $value = explode(',',$value); }else{ $value = (array)$value; } // 最终需要的效果 // Hook::add('bookhook','\addons\book\Book'); $addons[$key] = array_map('get_addon_class', $value); //array_map 将函数作用到数组中的每个值上 Hook::add($key,$addons[$key]); // 动态添加插件到某个钩子上 } cache('hooks',$addons); }else{ Hook::import($data,false); //批量导入插件 } }); ``` ## 获取插件类的类名 ``` /** * 获取插件类的类名 * @param [type] $name 插件名 * @param string $type [命名空间类型] * @param [type] $class [插件类名] * @return [string] */ function get_addon_class($name, $type = 'hook', $class = null){ //parseName转换命名格式 ,驼峰命名 book=>book GuestBook => guest_book,后面的参数1是首字母大写 $class = Loader::parseName(is_null($class) ? $name : $class, 1); switch($type){ case 'controller': $namespace = "\\addons\\" . $name . "\\controller\\" . $class; break; default: $namespace = "\\addons\\" . $name . "\\" . $class; } // 当一个类处于某个命名空间下时,class_exists必须补全命名空间 return class_exists($namespace) ? $namespace : ''; } ```