在PHP中使用反射技术的架构插件使用说明
2023-06-13 09:14:18 时间
反射API的插件方法是基于在运行时决定程序的功能来实现的,也就是说,它允许创建可选的接口方法,并在首次使用时检测到这部分接口方法,只有在插件中存在这部分接口的情况下,它们才会被用到.
假设拥有这样的接口
复制代码代码如下:
假设拥有这样的接口
interfaceIPlugin{
functiongetMenuItems();
functiongetArticles();
functiongetSideBars();
}
classSomepluginimplelentsIPlugin{
publicfunctiongetMenuItems(){
//没有菜单项
returnnull;
}
publicfunctiongetArticles(){//没有任何文章
returnnull;
}
publicfunctiongetSidBars(){
//有侧边
returnarray("sidbarItem");
}
}
[html]
这种情况并不太合理,因为满足了接口的要求,为大量方法添加了不会用到的函数体,如果在API中有数百个方法,这样是行不通的。
反射API提供了一种解决方法,使用get_declared_classes()函数取得当前加载的类,并检测哪个类实现了IPlugin"标记"的方法。
在这里写了一个使用反射查找插件的方法
[code]
functionfindPlugins(){
$plugins=array();
foreach(get_declared_classes()as$class){
$reflectionsClass=newReflectionClass($class);
if($reflectionsClass->implementsInterface("IPlugin")){
$plugins[]=$reflectionsClass;
}
}
return$plugins;
}
为了为了确定类是否实现了单个方法,可以使用REfectionClass类的hasMethod()方法。
确定用于菜单的类的成员
functioncomputerMenu(){
$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()函数,
如下publicmixedinvoke(stdclassobject,mixedargs=null)
另一方面,如果方法不是静态的,需要取得插件的一个实例来调用这个方法,要从Refectionclass对象取得类的一个实例,
调用它的newInstance()方法,然后再使用invoke()方法,返回实例传入就可以。
确定用于文章和侧边的类的成员
functioncomputeArticles(){
$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;
}
functioncomputeSidebars(){
$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;
}
创建一个实现了可选特性的反射式插件
classMyCoolPluginimplementsIPlugin{
publicstaticfunctiongetName(){return"MyCoolPlugin";}
publicstaticfunctiongetMenuItems(){
//菜单项的数字索引数组
returnarray(array("description"=>"MyCoolPlugin","link"=>"/MyCoolPlugin"));
}
publicstaticfunctiongetArticles(){
//文章的数字索引数组
returnarray(array("path"=>"/MyCoolPlugin","title"=>"Thisisareallycoolarticle",
"text"=>"Thisarticleiscoolbecause..."));
}
publicstaticfunctiongetSideBars(){
//文章的侧边栏索引数组
returnarray(array("sideBars"=>"/MyCoolPlugin"));
}
}
最后只要这样就可以使用这样插件了:
$menu=computeArticles();
$sidebars=computeSidebars();
$articles=computeArticles();
print_r($menu);
print_r($sidebars);
print_r($articles);
相关文章
- strstr函数php,strstr 函数用法[通俗易懂]
- 宝塔新建php文件实现百度自动推送
- PHP count()和sizeof():获取数组长度
- 一步步教你使用PHP调用Linux命令(php调用linux命令)
- 技术实现的网络系统PHP和MySQL结合:搭建网络系统的利器.(基于php和mysql)
- PHP命令执行php文件需要注意的问题详解编程语言
- Linux下构建高性能PHP环境(linux下的php)
- PHP实现MySQL乐观锁的技术研究(mysql乐观锁php)
- 开发使用PHP进行Redis项目开发(redis项目php)
- PHP探索MySQL的连接之路(php连接mysql)
- 技术使用PHP与MSSQL高效连接:实现无缝关联(php连接mssql的)
- PHP连接MSSQL:让你更快更好地实现数据互通(php接mssql)
- 学习PHP掌握MSSQL数据库操作的技巧(php如何操作mssql)
- PHP与MSSQL数据库之间的转义学习(php mssql 转义)
- 据使用PHP和MSSQL技术记录丰富的数据信息(php mssql记录数)
- PHP与MSSQL的融合——开启新的编程前程(php mssql 空白)
- PHP与MySQL的关联技术(php关联mysql)
- 随机头像PHP版
- php入门学习知识点一PHP与MYSql连接与查询
- nginx安装及配置支持php的教程(全)
- php缓存技术详细总结
- php另类上传图片的方法(PHP用Socket上传图片)