当前位置:Gxlcms > PHP教程 > 在PHP中使用反射技术的架构插件使用说明_PHP

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

时间:2021-07-01 10:21:17 帮助过:39人阅读

反射API的插件方法是基于在运行时决定程序的功能来实现的,也就是说,它允许创建可选的接口方法,并在首次使用时检测到这部分接口方法,只有在插件中存在这部分接口的情况下,它们才会被用到.
假设拥有这样的接口
代码如下:
  1. <br>interface IPlugin{ <br>function getMenuItems(); <br>function getArticles(); <br>function getSideBars(); <br>} <br>class Someplugin implelents IPlugin{ <br>public function getMenuItems(){ <br>//没有菜单项 <br>return null; <br>} <br>public function getArticles(){ //没有任何文章 <br>return null; <br>} <br>public function getSidBars(){ <br>//有侧边 <br>return array("sidbarItem'); <br>} <br>} <br>[html] <br>这种情况并不太合理,因为满足了接口的要求,为大量方法添加了不会用到的函数体,如果在API中有数百个方法,这样是行不通的。 <br>反射API提供了一种解决方法,使用get_declared_classes()函数取得当前加载的类,并检测哪个类实现了IPlugin"标记"的方法。 <br>在这里写了一个使用反射查找插件的方法 <br>[code] <br>function findPlugins(){ <br>$plugins=array(); <br>foreach (get_declared_classes() as $class){ <br>$reflectionsClass=new ReflectionClass($class); <br>if($reflectionsClass->implementsInterface('IPlugin')){ <br>$plugins[]=$reflectionsClass; <br>} <br>} <br>return $plugins; <br>} <br> <br>为了为了确定类是否实现了单个方法,可以使用REfectionClass类的hasMethod()方法。 <br>确定用于菜单的类的成员 <br><u></u> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>function computerMenu(){ <br>$menu=array(); <br>foreach (findPlugins() as $plugin){ <br>if($plugin->hasMethod('getMenuItems')){ <br>$reflectionMethod=$plugin->getMethod('getMenuItems'); <br>if($reflectionMethod->isStatic()){ <br>$items=$reflectionMethod->invoke(null); <br>}else{ <br>$pluginInstance=$plugin->newInstance(); <br>$items=$reflectionMethod->invoke($pluginInstance); <br>} <br>$menu=array_merge($menu,$items); <br>} <br>} <br>return $menu; <br>} <br> <br>得到类的实例后,需要检测是否能够静态检测调用API方法,如果方法是静态的,只需要调用 invoke()函数, <br>如下 public mixed invoke(stdclass object,mixed args=null) <br>另一方面,如果方法不是静态的,需要取得插件的一个实例来调用这个方法,要从Refectionclass对象取得类的一个实例, <br>调用 它的newInstance()方法,然后再使用invoke()方法,返回实例传入就可以。 <br>确定用于文章和侧边的类的成员 <br><u></u> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>function computeArticles(){ <br>$articles=array(); <br>foreach (findPlugins() as $plugin){ <br>if($plugin->hasMethod('getArticles')){ <br>$reflectionMethod=$plugin->getMethod('getArticles'); <br>if($reflectionMethod->isStatic()){ <br>$items=$reflectionMethod->invoke(null); <br>}else{ <br>$pluginInstance=$plugin->newInstance(); <br>$items=$reflectionMethod->invoke($pluginInstance); <br>} <br>$articles=array_merge($articles,$items); <br>} <br>} <br>return $articles; <br>} <br>function computeSidebars(){ <br>$sidebars=array(); <br>foreach (findPlugins() as $plugin){ <br>if($plugin->hasMethod('getSidebars')){ <br>$reflectionMethod=$plugin->getMethod('getSidebars'); <br>if($reflectionMethod->isStatic()){ <br>$items=$reflectionMethod->invoke(null); <br>}else{ <br>$pluginInstance=$plugin->newInstance(); <br>$items=$reflectionMethod->invoke($pluginInstance); <br>} <br>$sidebars=array_merge($sidebars,$items); <br>} <br>} <br>return $sidebars; <br>} <br> <br>创建一个实现了可选特性的反射式插件 <br><u></u> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>class MyCoolPlugin implements IPlugin{ <br>public static function getName(){return 'MyCoolPlugin';} <br>public static function getMenuItems(){ <br>//菜单项的数字索引数组 <br>return array(array('description'=>'MyCoolPlugin','link'=>'/MyCoolPlugin')); <br>} <br>public static function getArticles(){ <br>//文章的数字索引数组 <br>return array(array('path'=>'/MyCoolPlugin','title'=>'This is a really cool article', <br>'text'=>'This article is cool because...')); <br>} <br>public static function getSideBars(){ <br>//文章的侧边栏索引数组 <br>return array(array('sideBars'=>'/MyCoolPlugin')); <br>} <br>} <br> <br>最后只要这样就可以使用这样插件了: <br><u></u> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>$menu=computeArticles(); <br>$sidebars=computeSidebars(); <br>$articles=computeArticles(); <br>print_r($menu); <br>print_r($sidebars); <br>print_r($articles); </li></ol></pre></li></ol></pre></li></ol></pre></li></ol></pre>

人气教程排行