本文實例講述了PHP基于反射機制實現插件的可插拔設計。分享給大家供大家參考,具體如下:
說PHP和ASP等同的朋友們可以就此打住了,PHP支持反射,而且還是非常的強大。好了,我們開始今天的話題。
功能描述:
頁面擁有一個主導航菜單,里頭有默認連接若干。
插件統一存放在一個目錄,插件載入后會自動在導航菜單中增加上自己所需的鏈接。
插件載入時可執行一定的操作。
動態增刪插件無需改動代碼。
最終效果:
首頁,插件1,插件2
"首頁"是系統自帶的菜單項。"插件1"和"插件2"是由插件注冊的菜單項。
實現過程:
1. 文件結構
Learn
plugin
plugin1.php
plugin2.php
test.php
如此設計后,頁面入口為test.php,插件都存放在plugin目錄下,只要遍歷plugin目錄就可以找到所有的插件了。
2. 設計插件接口
1
2
3
4
5
|
interface IPlugin{ static function getname(); static function init(); static function getMenu(); } |
3. 插件內部實現接口
Plugin1實現接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php Class Welcome implements IPlugin{ static function getname(){ return 'Welcome (Plugin)' ; } static function getMenu(){ return array ( 'text' =>'插件1′, 'href' => 'http://www.google.com' ); } static function init(){ echo self::getname() . " 載入中…<br />" ; } } ?> |
Plugin2實現接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php Class ShowAD implements IPlugin{ static function getname(){ return 'Show AD (Plugin)' ; } static function getMenu(){ return array ( 'text' =>'插件2′, 'href' => 'http://www.live.com' ); } static function init(){ echo self::getname() . " 載入中…<br />" ; } } ?> |
4. 主頁面初始化主導航菜單
1
2
3
4
|
$menu [] = array ( 'text' => '首頁' , 'href' => '/test.php' ); |
5. 遍歷插件目錄,載入全部插件
1
2
3
4
5
6
7
8
|
$pluginPath = $_SERVER [ 'DOCUMENT_ROOT' ] . '/plugin' ; $dirHd = opendir( $pluginPath ); while ( $file = readdir( $dirHd )){ $pluginFilePath = $pluginPath . '/' . $file ; if ( $file != '.' && $file != '..' && is_file ( $pluginFilePath )){ include "$pluginFilePath" ; } } |
6. 過濾出實現了IPlugin接口的插件,并執行插件注入操作。
1
2
3
4
5
6
7
8
9
10
11
12
|
// 反射執行方法(注入菜單) foreach (get_declared_classes() as $class ){ $refClass = new ReflectionClass( $class ); if ( $refClass ->implementsInterface( 'IPlugin' )){ //插件初始化 $refClass ->getMethod( 'init' )->invoke(null); //獲取注入菜單 $menuItem = $refClass ->getMethod( 'getMenu' )->invoke(null); //合并菜單項 $menu = array_merge ( $menu , array ( $menuItem )); } } |
7. 主頁面輸出菜單HTML
1
2
3
|
foreach ( $menu as $m ){ echo "<a href='{$m['href']}'>{$m['text']}</a> " ; } |
注意第6部就是PHP的反射操作,是不是很簡單呢。分析下其中代碼,一個完整的反射操作時機只有2行代碼!
1
2
|
$refClass = new ReflectionClass( $class ); $menuItem = $refClass ->getMethod( 'getMenu' )->invoke(null); |
好了,反射的基本功能就介紹到這了。當然了,PHP的反射功能不僅僅如此,有興趣的自己發掘去吧。
希望本文所述對大家PHP程序設計有所幫助。