1. 程式人生 > >PHP用反射API實現自動載入

PHP用反射API實現自動載入

轉自:http://blog.csdn.net/many7hong7/article/details/52459192
<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/9/5 0005
 * Time: 9:44
 */
interface modules{
function execute();
}
//郵箱模組
class mailModule implements modules
{
//郵箱地址
public $address;
//設定地址方法
public function setAddress($address)
    {
$this->address=$address; } // 模組功能,開啟郵箱服務 public function execute() { echo "mail start<br>"; } } // userModule的依賴類 class user { public $username; public function __construct($name) { $this->username=$name; } } //使用者配置模組 class userModule implements modules { public $user; public function
setUser(user $user) { $this->user=$user; } public function execute() { //顯示當前使用者 echo "current user is {$this->user->username}<br>"; } } class autoLoadModule{ //配置陣列 private $configArray=array( 'mailModule'=>array( 'address'=>'[email protected]', ), 'userModule'=>array
( 'user'=>'manyhong', ), ); //模組列表 public $moduleList=array(); //模組初始化方法,本質是呼叫所有模組的初始化相關函式 public function init() { foreach ($this->configArray as $moduleName => $config) { //例項化一個關聯到模組類的reflectionClass物件 $moduleClass = new ReflectionClass($moduleName); //判斷模組是否存在 if (!$moduleClass->isSubclassOf('modules')) { throw new Exception("module:$moduleName doesn't exist"); } //例項化模組物件 $module = $moduleClass->newInstance(); //得到一組對應模組類的reflectionMethod物件 $methods=$moduleClass->getMethods(); //遍歷模組中的所有方法 foreach ($methods as $method){ //InitEngine初始化核心引擎,需要傳入模組物件和reflectionMethod物件和相關配置檔案 $this->InitEngine($module,$method,$config); } $this->moduleList[]=$module; } } public function InitEngine(modules $module,ReflectionMethod $method,$moduleConfigs){ //獲取方法名 $methodName=$method->getName(); //獲取方法的引數列表 $args=$method->getParameters(); //過濾出符合系統要求的模組初始化方法:命名規則setXXX,引數有且只有一個 if(substr($methodName,0,3)!= 'set' || count($args)!=1){ return false; } //從方法名中獲取需要初始化的屬性(所以上文我們才對設定屬性方法的命名有要求) $property=strtolower(substr($methodName,3)); //如果配置檔案中該配置項為空則直接返回false if(is_null($moduleConfigs[$property])){ return false; } //如果配置項不為空,接著判斷引數型別,決定是否需要例項化依賴類 //呼叫reflectionParameter::getClass方法()獲取引數型別 $parameterType=$args[0]->getClass(); //如果是字串型別 if(is_null($parameterType)){ //呼叫reflectionMethod::invoke方法,傳入方法所在物件和方法實參 $method->invoke($module,$moduleConfigs[$property]); return true; }else{ /*如果是物件型別,則需要初始化依賴類物件後再傳入*/ $method->invoke($module,new$property($moduleConfigs[$property])); return true; } } //呼叫所有模組功能 public function run(){ foreach ($this->moduleList as $module){ $module->execute(); } } } //例項化這個自動載入類物件 $obj=new autoLoadModule(); //自動載入模組並根據配置完成模組初始化工作 $obj->init(); //然後就可以使用模組了 $obj->run();