在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 相关文章推荐
PHP脚本的10个技巧(6)
Oct 09 PHP
PHP实时显示输出
Oct 02 PHP
php 移除数组重复元素的一点说明
Nov 27 PHP
PHP中的float类型使用说明
Jul 27 PHP
PHP删除特定数组内容并且重建数组索引的方法.
Mar 25 PHP
使用array mutisort 实现按某字段对数据排序
Jun 18 PHP
PHP中使用sleep造成mysql读取失败的案例和解决方法
Aug 21 PHP
php生成二维码
Aug 10 PHP
Symfony的安装和配置方法
Mar 17 PHP
php面向对象值单例模式
May 03 PHP
php实现的mysqldb读写分离操作类示例
Feb 07 PHP
Yii实现复选框批量操作实例代码
Mar 15 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
为什么夜间收到的中波电台比白天多
2021/03/01 无线电
一个简单的自动发送邮件系统(二)
2006/10/09 PHP
php class类的用法详细总结
2013/10/17 PHP
使用PHP破解防盗链图片的一个简单方法
2014/06/07 PHP
Laravel5权限管理方法详解
2016/07/26 PHP
Yii2框架实现登录、退出及自动登录功能的方法详解
2017/10/24 PHP
神奇的代码 通杀各种网站-可随意修改复制页面内容
2008/07/17 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
JavaScript Math 对象常用方法总结
2016/04/28 Javascript
JavaScript String 对象常用方法详解
2016/05/13 Javascript
JQ选择器_选择同类元素的第N个子元素的实现方法
2016/09/08 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
js实现图片360度旋转
2017/01/22 Javascript
JS动态生成年份和月份实例代码
2017/02/04 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
2017/03/04 Javascript
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
关于vue的语法规则检测报错问题的解决
2018/05/21 Javascript
vue根据值给予不同class的实例
2018/09/29 Javascript
JS实现无限轮播无倒退效果
2020/09/21 Javascript
python在多玩图片上下载妹子图的实现代码
2013/08/13 Python
Python中使用ConfigParser解析ini配置文件实例
2014/08/30 Python
Python实现快速排序算法及去重的快速排序的简单示例
2016/06/26 Python
Python运行不显示DOS窗口的解决方法
2018/10/22 Python
对python pandas读取剪贴板内容的方法详解
2019/01/24 Python
python实现两张图片拼接为一张图片并保存
2019/07/16 Python
python+rsync精确同步指定格式文件
2019/08/29 Python
python实现图片横向和纵向拼接
2020/03/05 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
2020/12/07 Python
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
经典c++面试题二
2015/08/14 面试题
大学生最新职业生涯规划书范文
2014/01/12 职场文书
公务员职业生涯规划书范文  
2014/01/19 职场文书
模具专业毕业生自荐书范文
2014/02/19 职场文书
工程造价专业大学生职业规划范文
2014/03/09 职场文书
国庆节活动总结
2014/08/26 职场文书
七年级作文之关于奶奶
2019/10/29 职场文书