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自动更新新闻DIY
Oct 09 PHP
PHP5.2中date()函数显示时间与北京时间相差8小时的解决办法
May 28 PHP
PHP 数据结构 算法 三元组 Triplet
Jul 02 PHP
比较详细PHP生成静态页面教程
Jan 10 PHP
PHP最常用的2种设计模式工厂模式和单例模式介绍
Aug 14 PHP
php 中文字符串首字母的获取函数分享
Nov 04 PHP
php实现json编码的方法
Jul 30 PHP
PHP的PDO操作简单示例
Mar 30 PHP
php图片添加水印例子
Jul 20 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
Jul 21 PHP
PHP用函数嵌入网站访问量计数器
Oct 27 PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
Nov 23 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
zend framework文件上传功能实例代码
2013/12/25 PHP
php解析url并得到url中的参数及获取url参数的四种方式
2015/10/26 PHP
PHP工程师VIM配置分享
2015/12/15 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
2016/03/16 PHP
php使用正则验证中文
2016/04/06 PHP
完美的php分页类
2017/10/24 PHP
详解PHP素材图片上传、下载功能
2019/04/12 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题分析
2007/08/12 Javascript
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
详解JavaScript数组过滤相同元素的5种方法
2017/05/23 Javascript
基于zepto.js实现手机相册功能
2017/07/11 Javascript
Vue.use源码学习小结
2018/06/20 Javascript
小程序实现留言板
2018/11/02 Javascript
Vue.js的复用组件开发流程完整记录
2018/11/29 Javascript
前端深入理解Typescript泛型概念
2020/03/09 Javascript
Node登录权限验证token验证实现的方法示例
2020/05/25 Javascript
js数组的基本使用总结
2021/01/18 Javascript
Python matplotlib绘制饼状图功能示例
2019/09/10 Python
python3中pip3安装出错,找不到SSL的解决方式
2019/12/12 Python
python新式类和经典类的区别实例分析
2020/03/23 Python
python opencv 实现读取、显示、写入图像的方法
2020/06/08 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
python下载的库包存放路径
2020/07/27 Python
python从ftp获取文件并下载到本地
2020/12/05 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
2021/01/27 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
Tessabit美国:集世界奢侈品和设计师品牌的意大利精品买手店
2020/06/29 全球购物
怎样在 Applet 中建立自己的菜单(MenuBar/Menu)?
2012/06/20 面试题
红领巾广播站广播稿(3篇)
2014/09/20 职场文书
AJAX实现省市县三级联动效果
2021/10/16 Javascript
SQL Server中的游标介绍
2022/05/20 SQL Server