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 error_log 函数的使用
Apr 13 PHP
用PHP的ob_start() 控制您的浏览器cache
Aug 03 PHP
PHP排序之二维数组的按照字母排序实现代码
Aug 13 PHP
php定时删除文件夹下文件(清理缓存文件)
Jan 23 PHP
Yii把CGridView文本框换成下拉框的方法
Dec 03 PHP
PHP获取一年中每个星期的开始和结束日期的方法
Feb 12 PHP
PHP永久登录、记住我功能实现方法和安全做法
Apr 27 PHP
PHP异常处理浅析
May 12 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
Nov 27 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
Mar 15 PHP
PHP后期静态绑定实例浅析
Dec 21 PHP
针对PHP开发安全问题的相关总结
Mar 22 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嵌套输出缓冲代码实例
2015/05/12 PHP
php 解析xml 的四种方法详细介绍
2016/10/26 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
Javascript核心读书有感之表达式和运算符
2015/02/11 Javascript
JavaScript对象参数的引用传递
2016/01/14 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
2017/10/14 jQuery
详解vue-cli3使用
2018/08/14 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
[02:22]完美世界DOTA2联赛PWL S3 集锦第一期
2020/12/15 DOTA
以911新闻为例演示Python实现数据可视化的教程
2015/04/23 Python
深入理解python中的atexit模块
2017/03/07 Python
Django内容增加富文本功能的实例
2017/10/17 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
浅谈Series和DataFrame中的sort_index方法
2018/06/07 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
华为校园招聘上机笔试题 扑克牌大小(python)
2020/04/22 Python
OpenCV3.0+Python3.6实现特定颜色的物体追踪
2019/07/23 Python
pytorch中图像的数据格式实例
2020/02/11 Python
关于Python不换行输出和不换行输出end=““不显示的问题(亲测已解决)
2020/10/27 Python
详解css3 flex弹性盒自动铺满写法
2020/09/17 HTML / CSS
逻辑链路控制协议
2016/10/01 面试题
公务员职务工作的自我评价
2013/11/01 职场文书
元旦晚会上单位领导演讲稿
2014/01/05 职场文书
护士思想汇报
2014/01/12 职场文书
在校生自我鉴定
2014/01/23 职场文书
50岁生日感言
2014/01/23 职场文书
平安家庭示范户事迹
2014/06/02 职场文书
校园广播稿精选
2014/10/01 职场文书
幼儿园园长新年寄语2015
2014/12/08 职场文书
工作态度检讨书范文
2015/05/06 职场文书
同学聚会感言一句话
2015/07/30 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python
雄兵连:第三季先行图公开,天使恶魔联合,银河之力的新力量
2021/06/11 国漫
Python学习之异常中的finally使用详解
2022/03/16 Python