最近在使用ThinkPHP5开发应用,之前习惯了一些插件开发,感觉很好且,但基于现在文档不是很完善,所以自己研究了一下基础功能。将TP3.2中的插件功能迁移了过来。
加入插件的方法:
1、在系统的index.php入口中加入如下配置
// 插件目录 define('ADDON_PATH', __DIR__ . '/../addons/'); // 开启系统行为 define('APP_HOOK', true);
2、在数据库中加入addons插件表和hooks钩子表
CREATE TABLE `addons` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(40) NOT NULL COMMENT '插件名或标识', `title` varchar(20) NOT NULL DEFAULT '' COMMENT '中文名', `description` text COMMENT '插件描述', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态', `config` text COMMENT '配置', `author` varchar(40) DEFAULT '' COMMENT '作者', `version` varchar(20) DEFAULT '' COMMENT '版本号', `create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '安装时间', `has_adminlist` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否有后台列表', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='插件表'; CREATE TABLE `hooks` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(40) NOT NULL DEFAULT '' COMMENT '钩子名称', `description` text NOT NULL COMMENT '描述', `type` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '类型', `update_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', `addons` varchar(255) NOT NULL DEFAULT '' COMMENT '钩子挂载的插件 '',''分割', `status` tinyint(2) DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
3、在ThinkPHP5的根目录中创建addons目录
www WEB项目目录 ├─composer.json composer定义文件 ├─README.md README文件 ├─LICENSE.txt 授权说明文件 ├─addons 插件目录(新增)├─application 应用目录 │ ├─common 公共模块目录(可以更改) │ ├─runtime 应用的运行时目录(可写,可定制) │ ├─module 模块目录 │ │ └─ ... 更多类库目录 │ ├─common.php 公共函数文件 │ ├─config.php 公共配置文件 │ ├─route.php 路由配置文件 │ └─database.php 数据库配置文件 │ ├─public WEB目录(对外访问目录) │ ├─index.php 入口文件 │ ├─.htaccess 用于apache的重写 │ └─router.php 快速测试文件(用于PHP内置webserver) │ ├─thinkphp 框架系统目录
4、在application中的common.php公共函数里添加两个公共方法
/** * 获取插件类的类名 * @param strng $name 插件名 * @param string $ext 扩展名 */ function get_addon_class($name, $ext = EXT) { // 初始化命名空间及类名 $class = "addons\\{$name}\\" . ucfirst($name); return $class; } /** * 处理插件钩子 * @param string $hook 钩子名称 * @param mixed $params 传入参数 * @return void */ function hook($hook, $params = []) { // 钩子调用 \think\Hook::listen($hook, $params); }
5、在application目录下创建common模块,在common模块中创建behavior行为目录,在公共行为目录中创建Hooks.php钩子行为插件,内容如下:
<?php // +---------------------------------------------------------------------- // | zzstudio [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2016 http://www.zzstudio.net All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: Byron Sampson <xiaobo.sun@gzzstudio.net> // +---------------------------------------------------------------------- namespace app\common\behavior; use think\Hook; class Hooks { public function run(&$param = []) { if(defined('BIND_MODULE') && BIND_MODULE === 'Install') return; // 动态加入命名空间 \think\Loader::addNamespace('addons', ADDON_PATH); // 获取钩子数据 $data = S('hooks'); if(!$data){ $hooks = M('Hooks')->getField('name,addons'); // 获取钩子的实现插件信息 foreach ($hooks as $key => $value) { if($value){ $map['status'] = 1; $names = explode(',',$value); $map['name'] = ['IN', $names]; $data = M('Addons')->where($map)->getField('id,name'); if($data){ $addons = array_intersect($names, $data); Hook::add($key, array_map('get_addon_class', $addons)); } } } S('hooks', Hook::get()); }else{ Hook::import($data, false); } } }
6、在application目录中创建tags.php行为配置文件,并且加入内容
<?php // 系统行为定义 return [ 'app_init' => [ 'app\\common\\behavior\\Hooks' ], 'action_begin'=> [ ], 'app_end'=> [ ] ];
到此为止,插件功能就集成完毕了。
接下来我们做个简单的插件试一下:
1、在addons目录中创建一个Base.php 插件的基类
<?php // +---------------------------------------------------------------------- // | addons [ WE CAN DO IT JUST ZZSTUDIO IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2015 http://www.zzstudio.net All rights reserved. // +---------------------------------------------------------------------- // | Author: byron sampson <xiaobo.sun@zzstudio.net> // +---------------------------------------------------------------------- namespace addons; /** * 插件类 * @author byron sampson <xiaobo.sun@zzstudio.net> */ abstract class Base{ /** * 视图实例对象 * @var view * @access protected */ protected $view = null; /** * $info = array( * 'name'=>'Editor', * 'title'=>'编辑器', * 'description'=>'用于增强整站长文本的输入和显示', * 'status'=>1, * 'author'=>'thinkphp', * 'version'=>'0.1' * ) */ public $info = array(); public $addon_path = ''; public $config_file = ''; public $custom_config = ''; public $admin_list = array(); public $custom_adminlist = ''; public $access_url = array(); /** * 基类构造函数 * Base constructor. */ public function __construct() { $this->view = new \think\View(); $this->addon_path = ADDON_PATH . $this->getName() . '/'; $TMPL_PARSE_STRING = C('parse_str'); $TMPL_PARSE_STRING['__ADDONROOT__'] = $TMPL_PARSE_STRING['__ADDONS__'] . '/' . $this->getName(); C('parse_str', $TMPL_PARSE_STRING); if(is_file($this->addon_path . 'config.php')){ $this->config_file = $this->addon_path . 'config.php'; } } /** * 模板主题设置 * @access protected * @param string $theme 模版主题 * @return Action */ final protected function theme($theme) { $this->view->theme($theme); return $this; } /** * 模板变量赋值 * @access protected * @param mixed $name 要显示的模板变量 * @param mixed $value 变量的值 * @return Action */ final protected function assign($name, $value='') { $this->view->assign($name,$value); return $this; } //用于显示模板的方法 final protected function fetch($templateFile = CONTROLLER_NAME) { if(!is_file($templateFile)){ $templateFile = $this->addon_path . $templateFile . ".html"; if(!is_file($templateFile)){ E(L('_TEMPLATE_NOT_EXIST_') . ":$templateFile"); } } return $this->view->fetch($templateFile); } /** * 获取插件名 * @return string */ final public function getName() { $class = get_class($this); list($space, $name, $class) = explode('\\', $class); return $name; } /** * 检查配置信息是否完整 * @return bool */ final public function checkInfo() { $info_check_keys = array('name','title','description','status','author','version'); foreach ($info_check_keys as $value) { if(!array_key_exists($value, $this->info)) return false; } return true; } /** * 获取插件的配置数组 */ final public function getConfig($name = '') { static $_config = []; if(empty($name)){ $name = $this->getName(); } if(isset($_config[$name])){ return $_config[$name]; } $map['name'] = $name; $map['status'] = 1; $config = M('Addons')->where($map)->getField('config'); if($config){ $config = json_decode($config, true); }else{ $config = []; $temp_arr = include $this->config_file; foreach ($temp_arr as $key => $value) { if($value['type'] == 'group'){ foreach ($value['options'] as $gkey => $gvalue) { foreach ($gvalue['options'] as $ikey => $ivalue) { $config[$ikey] = $ivalue['value']; } } }else{ $config[$key] = $temp_arr[$key]['value']; } } } $_config[$name] = $config; return $config; } /** * 必须实现安装 * @return mixed */ abstract public function install(); /** * 必须卸载插件方法 * @return mixed */ abstract public function uninstall(); }
2、在插件表(addons),钩子表(hooks)中加入相应的数据
INSERT INTO `addons` (`id`, `name`, `title`, `description`, `status`, `config`, `author`, `version`, `create_time`, `has_adminlist`) VALUES ('2', 'test', 'test插件', 'test插件简介', '1', NULL, 'byron sampson', '0.1', '1438154545', '0'); INSERT INTO .`hooks` (`id`, `name`, `description`, `type`, `update_time`, `addons`, `status`) VALUES ('21', 'demo', 'demo钩子', '1', '1384481614', 'test', '1');
3、在addons目录中创建一个test目录,且内部创建一个Test.php插件类
<?php // +---------------------------------------------------------------------- // | test [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2016 http://www.zzstudio.net All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: Byron Sampson <xiaobo.sun@gzzstudio.net> // +---------------------------------------------------------------------- namespace addons\test; class Test extends \addons\Base { /** * 实现demo钩子 * @param array $params */ public function demo($params = []) { echo 'demo hook!page is ' . $params['p']; } /** * 安装方法 */ public function install() { // TODO: Implement install() method. } /** * 卸载方法 */ public function uninstall() { // TODO: Implement uninstall() method. } }
4、在控制器中使用hook方法来调用钩子
hook('demo', ['p'=>'page']);
5、ok,大功告成
© 版权声明
本站网络名称:
乐商网络
本站永久网址:
https://ishoud.com
网站侵权说明:
本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长QQ810066660删除处理。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
THE END
暂无评论内容