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

反射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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值