>백엔드 개발 >PHP 튜토리얼 >PHP의 리플렉션 기술을 사용한 플러그인 예제에 대한 자세한 설명

PHP의 리플렉션 기술을 사용한 플러그인 예제에 대한 자세한 설명

伊谢尔伦
伊谢尔伦원래의
2017-06-30 10:39:211240검색

Reflection 기반 플러그인Architecture은 실제로 템플릿이 아니기 때문에 패턴으로 분류되지 않고 프로그램 아키텍처를 형성하기 위해 함께 결합되는 일련의 개념입니다.

리플렉션 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; 
}

클래스가 단일 메서드를 구현하는지 확인하려면 hasMethod() 메서드를 사용할 수 있습니다. REfectionClass 클래스의
메뉴에 사용되는 클래스의 멤버를 확인합니다.

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 메서드를 정적탐지할 수 있는지 확인해야 합니다. 메서드가 정적이면 호출만 하면 됩니다. 호출() 함수는
공용 혼합 호출(stdclass 객체, 혼합 인수=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의 리플렉션 기술을 사용한 플러그인 예제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.