PHP基于反射机制实现插件的可插拔设计详解


Posted in PHP onNovember 10, 2016

本文实例讲述了PHP基于反射机制实现插件的可插拔设计。分享给大家供大家参考,具体如下:

说PHP和ASP等同的朋友们可以就此打住了,PHP支持反射,而且还是非常的强大。好了,我们开始今天的话题。

功能描述:

页面拥有一个主导航菜单,里头有默认连接若干。
插件统一存放在一个目录,插件载入后会自动在导航菜单中增加上自己所需的链接。
插件载入时可执行一定的操作。
动态增删插件无需改动代码。

最终效果:

首页,插件1,插件2

"首页"是系统自带的菜单项。"插件1"和"插件2"是由插件注册的菜单项。

实现过程:

1. 文件结构

Learn
plugin
plugin1.php
plugin2.php
test.php

如此设计后,页面入口为test.php,插件都存放在plugin目录下,只要遍历plugin目录就可以找到所有的插件了。

2. 设计插件接口

interface IPlugin{
static function getname();
static function init();
static function getMenu();
}

3. 插件内部实现接口

Plugin1实现接口:

<?php
Class Welcome implements IPlugin{
static function getname(){
return 'Welcome (Plugin)';
}
static function getMenu(){
return array(
'text'=>'插件1′,
'href'=>'http://www.google.com'
);
}
static function init(){
echo self::getname() . " 载入中…<br />";
}
}
?>

Plugin2实现接口:

<?php
Class ShowAD implements IPlugin{
static function getname(){
return 'Show AD (Plugin)';
}
static function getMenu(){
return array(
'text'=>'插件2′,
'href'=>'http://www.live.com'
);
}
static function init(){
echo self::getname() . " 载入中…<br />";
}
}
?>

4. 主页面初始化主导航菜单

$menu[] = array(
'text'=>'首页',
'href'=>'/test.php'
);

5. 遍历插件目录,载入全部插件

$pluginPath = $_SERVER['DOCUMENT_ROOT'] . '/plugin';
$dirHd = opendir($pluginPath);
while ($file = readdir($dirHd)){
$pluginFilePath = $pluginPath . '/' . $file;
if($file!='.' && $file!='..' && is_file($pluginFilePath)){
include "$pluginFilePath";
}
}

6. 过滤出实现了IPlugin接口的插件,并执行插件注入操作。

// 反射执行方法(注入菜单)
foreach (get_declared_classes() as $class){
$refClass = new ReflectionClass($class);
if($refClass->implementsInterface('IPlugin')){
//插件初始化
$refClass->getMethod('init')->invoke(null);
//获取注入菜单
$menuItem = $refClass->getMethod('getMenu')->invoke(null);
//合并菜单项
$menu = array_merge($menu, array($menuItem));
}
}

7. 主页面输出菜单HTML

foreach ($menu as $m){
echo "<a href='{$m['href']}'>{$m['text']}</a> ";
}

注意第6部就是PHP的反射操作,是不是很简单呢。分析下其中代码,一个完整的反射操作时机只有2行代码!

$refClass = new ReflectionClass($class);
$menuItem = $refClass->getMethod('getMenu')->invoke(null);

好了,反射的基本功能就介绍到这了。当然了,PHP的反射功能不仅仅如此,有兴趣的自己发掘去吧。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php和数据库结合的一个简单的web实例 代码分析 (php初学者)
Jul 28 PHP
PHP数组 为文章加关键字连接 文章内容自动加链接
Dec 29 PHP
php对图像的各种处理函数代码小结
Jul 08 PHP
ThinkPHP处理Ajax返回的方法
Nov 22 PHP
PHP实现无限极分类图文教程
Nov 25 PHP
深入浅出php socket编程
May 13 PHP
修复ShopNC使用QQ 互联时提示100010 错误
Nov 08 PHP
thinkPHP中验证码的简单使用方法
Dec 26 PHP
Smarty模板常见的简单应用分析
Nov 15 PHP
PHP获取页面执行时间的方法(推荐)
Dec 10 PHP
PHP获取当前系统时间的方法小结
Oct 03 PHP
PHP接入微信H5支付的方法示例
Oct 28 PHP
PHP yii实现model添加默认值的方法(两种方法)
Nov 10 #PHP
PHP实现的曲线统计图表示例
Nov 10 #PHP
PHP  Yii清理缓存的实现方法
Nov 10 #PHP
PHP模拟http请求的方法详解
Nov 09 #PHP
Linux平台PHP5.4设置FPM线程数量的方法
Nov 09 #PHP
浅析php-fpm静态和动态执行方式的比较
Nov 09 #PHP
PHP带节点操作的无限分类实现方法详解
Nov 09 #PHP
You might like
PHP面向对象分析设计的61条军规小结
2010/07/17 PHP
php Session无效分析资料整理
2016/11/29 PHP
在vs2010中调试javascript代码方法
2011/02/11 Javascript
css transform 3D幻灯片特效实现步骤解读
2013/03/27 Javascript
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
js鼠标滑过图片震动特效的方法
2015/02/17 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
2016/03/01 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
Vue.js Ajax动态参数与列表显示实现方法
2016/10/20 Javascript
小程序中canvas的drawImage方法参数使用详解
2019/07/04 Javascript
微信小程序中button去除默认的边框实例代码
2019/08/01 Javascript
antd Form组件方法getFieldsValue获取自定义组件的值操作
2020/10/29 Javascript
[45:34]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.18
2020/12/19 DOTA
Python发送Email方法实例
2014/08/21 Python
python传递参数方式小结
2015/04/17 Python
Python实现把回车符\r\n转换成\n
2015/04/23 Python
Python基础教程之利用期物处理并发
2018/03/29 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
Python yield生成器和return对比代码实例
2020/04/20 Python
纯css3显示隐藏一个div特效的具体实现
2014/02/10 HTML / CSS
英国领先的电动可调床制造商:Laybrook
2019/12/26 全球购物
创意活动策划书
2014/01/15 职场文书
寒假实习自荐信
2014/01/26 职场文书
八年级美术教学反思
2014/02/02 职场文书
战略合作意向书
2014/07/29 职场文书
踏青活动策划方案
2014/08/19 职场文书
代办出身证明书
2014/10/21 职场文书
地震慰问信
2015/02/14 职场文书
酒店总经理岗位职责
2015/04/01 职场文书
建筑质检员岗位职责
2015/04/08 职场文书
关于召开会议的通知
2015/04/15 职场文书
2015中学教学工作总结
2015/07/22 职场文书
不会写演讲稿,快来看看这篇文章!
2019/08/06 职场文书
Python的property属性详细讲解
2022/04/11 Python
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL