最近在使用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']);
本文轉自:https://qqnin.com/35_81.html
