리플렉션 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 메소드를 정적으로 호출할 수 있는지 확인해야 합니다. 호출() 함수만 호출하면 됩니다.
다음 공용 혼합 호출(stdclass object,mixed args=null)
반면, 메소드가 정적이 아닌 경우 인스턴스를 가져와야 합니다. 이 메소드를 호출하려면 Refectionclass 객체에서 클래스의 인스턴스를 가져와야 합니다.
newInstance() 메소드를 호출한 다음 호출() 메소드를 사용하여 인스턴스를 반환하고 전달합니다.
기사 및 측면에 사용되는 클래스 멤버 결정
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 중국어 웹사이트를 주목하세요!