在PHP中使用反射技术的架构插件使用说明


Posted in PHP onMay 18, 2010

反射API的插件方法是基于在运行时决定程序的功能来实现的,也就是说,它允许创建可选的接口方法,并在首次使用时检测到这部分接口方法,只有在插件中存在这部分接口的情况下,它们才会被用到.
假设拥有这样的接口

interface IPlugin{ 
function getMenuItems(); 
function getArticles(); 
function getSideBars(); 
} 
class Someplugin implelents IPlugin{ 
public function getMenuItems(){ 
//没有菜单项 
return null; 
} 
public function getArticles(){ //没有任何文章 
return null; 
} 
public function getSidBars(){ 
//有侧边 
return array("sidbarItem'); 
} 
} 
[html] 
这种情况并不太合理,因为满足了接口的要求,为大量方法添加了不会用到的函数体,如果在API中有数百个方法,这样是行不通的。 
反射API提供了一种解决方法,使用get_declared_classes()函数取得当前加载的类,并检测哪个类实现了IPlugin"标记"的方法。 
在这里写了一个使用反射查找插件的方法 
[code] 
function findPlugins(){ 
$plugins=array(); 
foreach (get_declared_classes() as $class){ 
$reflectionsClass=new ReflectionClass($class); 
if($reflectionsClass->implementsInterface('IPlugin')){ 
$plugins[]=$reflectionsClass; 
} 
} 
return $plugins; 
}

为了为了确定类是否实现了单个方法,可以使用REfectionClass类的hasMethod()方法。
确定用于菜单的类的成员
function computerMenu(){ 
$menu=array(); 
foreach (findPlugins() as $plugin){ 
if($plugin->hasMethod('getMenuItems')){ 
$reflectionMethod=$plugin->getMethod('getMenuItems'); 
if($reflectionMethod->isStatic()){ 
$items=$reflectionMethod->invoke(null); 
}else{ 
$pluginInstance=$plugin->newInstance(); 
$items=$reflectionMethod->invoke($pluginInstance); 
} 
$menu=array_merge($menu,$items); 
} 
} 
return $menu; 
}

得到类的实例后,需要检测是否能够静态检测调用API方法,如果方法是静态的,只需要调用 invoke()函数,
如下 public mixed invoke(stdclass object,mixed args=null)
另一方面,如果方法不是静态的,需要取得插件的一个实例来调用这个方法,要从Refectionclass对象取得类的一个实例,
调用 它的newInstance()方法,然后再使用invoke()方法,返回实例传入就可以。
确定用于文章和侧边的类的成员
function computeArticles(){ 
$articles=array(); 
foreach (findPlugins() as $plugin){ 
if($plugin->hasMethod('getArticles')){ 
$reflectionMethod=$plugin->getMethod('getArticles'); 
if($reflectionMethod->isStatic()){ 
$items=$reflectionMethod->invoke(null); 
}else{ 
$pluginInstance=$plugin->newInstance(); 
$items=$reflectionMethod->invoke($pluginInstance); 
} 
$articles=array_merge($articles,$items); 
} 
} 
return $articles; 
} 
function computeSidebars(){ 
$sidebars=array(); 
foreach (findPlugins() as $plugin){ 
if($plugin->hasMethod('getSidebars')){ 
$reflectionMethod=$plugin->getMethod('getSidebars'); 
if($reflectionMethod->isStatic()){ 
$items=$reflectionMethod->invoke(null); 
}else{ 
$pluginInstance=$plugin->newInstance(); 
$items=$reflectionMethod->invoke($pluginInstance); 
} 
$sidebars=array_merge($sidebars,$items); 
} 
} 
return $sidebars; 
}

创建一个实现了可选特性的反射式插件
class MyCoolPlugin implements IPlugin{ 
public static function getName(){return 'MyCoolPlugin';} 
public static function getMenuItems(){ 
//菜单项的数字索引数组 
return array(array('description'=>'MyCoolPlugin','link'=>'/MyCoolPlugin')); 
} 
public static function getArticles(){ 
//文章的数字索引数组 
return array(array('path'=>'/MyCoolPlugin','title'=>'This is a really cool article', 
'text'=>'This article is cool because...')); 
} 
public static function getSideBars(){ 
//文章的侧边栏索引数组 
return array(array('sideBars'=>'/MyCoolPlugin')); 
} 
}

最后只要这样就可以使用这样插件了:
$menu=computeArticles(); 
$sidebars=computeSidebars(); 
$articles=computeArticles(); 
print_r($menu); 
print_r($sidebars); 
print_r($articles);
PHP 相关文章推荐
VFP与其他应用程序的集成
Oct 09 PHP
处理php自动反斜杠的函数代码
Jan 05 PHP
Smarty Foreach 使用说明
Mar 23 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
Apr 22 PHP
php天翼开放平台短信发送接口实现方法
Dec 22 PHP
PHP保存带BOM文件的方法
Feb 12 PHP
php数组键名技巧小结
Feb 17 PHP
php获取百度收录、百度热词及百度快照的方法
Apr 02 PHP
ThinkPHP控制器详解
Jul 27 PHP
php单例模式的简单实现方法
Jun 10 PHP
PHP 的Opcache加速的使用方法
Dec 29 PHP
详解Laravel5.6 Passport实现Api接口认证
Jul 27 PHP
PHP 写文本日志实现代码
May 18 #PHP
php 随机记录mysql rand()造成CPU 100%的解决办法
May 18 #PHP
PHP array_flip() 删除重复数组元素专用函数
May 16 #PHP
mysql下创建字段并设置主键的php代码
May 16 #PHP
php带密码功能并下载远程文件保存本地指定目录 修改加强版
May 16 #PHP
ezSQL PHP数据库操作类库
May 16 #PHP
php 提速工具eAccelerator 配置参数详解
May 16 #PHP
You might like
PHP的中问验证码
2006/11/25 PHP
php 修改上传文件大小限制实例详解
2016/10/23 PHP
PHP addAttribute()函数讲解
2019/02/03 PHP
JavaScript 实现??打印?理
2007/04/28 Javascript
jQuery的强大选择器小结
2009/12/27 Javascript
jquery 图片上传按比例预览插件集合
2011/05/28 Javascript
stream.js 一个很小、完全独立的Javascript类库
2011/10/28 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
js如何打印object对象
2015/10/16 Javascript
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
vue打包相关细节整理(小结)
2018/09/28 Javascript
详解React 的几种条件渲染以及选择
2018/10/23 Javascript
详解vue组件中使用路由方法
2019/02/12 Javascript
vue监听dom大小改变案例
2020/07/29 Javascript
关于python pyqt5安装失败问题的解决方法
2017/08/08 Python
python绘制铅球的运行轨迹代码分享
2017/11/14 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
Python实现将数据写入netCDF4中的方法示例
2018/08/30 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
2019/07/05 Python
python3 简单实现组合设计模式
2020/07/02 Python
Python pysnmp使用方法及代码实例
2020/08/24 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
英国健身仓库:Bodybuilding Warehouse
2019/03/06 全球购物
意大利单身交友网站:Meetic
2020/07/12 全球购物
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
正规的求职信范文分享
2013/12/11 职场文书
项目开发计划书
2014/01/09 职场文书
女方回门宴答谢词
2014/01/14 职场文书
小学优秀班主任事迹材料
2014/05/17 职场文书
社区健康教育工作方案
2014/06/03 职场文书
作文评语集锦
2014/12/25 职场文书
文体活动总结
2015/02/04 职场文书
离婚承诺书格式范文
2015/05/04 职场文书