转自: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'=>'1151864810@qq.com',
),
'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();