您好,欢迎访问一九零五行业门户网

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_ declare d_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->is static ()){ $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中使用反射技术插件实例详解的详细内容。
其它类似信息

推荐信息