最近正在搞对象依赖,除了配置文件,还有就是微核心容器 PicoContainer 比较流行?
php5因为参数可以有 Type Hinting 类型指示,照说也可以做
测试了下可行,谁搞过这方面,也拿出来骚一下……
//以下A/B/C 3个类,相互间有依赖,通过构造函数注入
class  A{
}class B {
protected $o; function __construct(A $o) {
$this->o=$o;
}
}class C {
protected $o;
protected $oo; function __construct(B $o,A $oo) {
$this->o=$o;
$this->oo=$oo;
}
}//测试的微核心容器类。没搞父子容器啥的。通过参数的类型指示/反射,创建对象时自动注入其依赖的其他对象
class PHPiocContainer {
protected $regClassNames=array();
protected $classConstructIocs=array(); //注册类
public function regClass($className) {
$this->regClassNames[]=$className;
} //返回对象
public function getObject($className) {
return $this->createObject($className);
} //递归创建对象
protected function createObject($className) {
if(!in_array($className,$this->regClassNames)){
exit('class is not registered');
} $p=array(); foreach($this->getClassConstructIoc($className) as $hintClass){
if(!empty($hintClass)){
$p[]=$this->createObject($hintClass);
}
} for ($i = 0; $i < count($p); $i++) {
$newP .= '$p['.$i.'],';
}
$newP = rtrim($newP,','); return eval("return new $className($newP);");
}

//获得 类构造函数 其所有参数的类型指示
protected function &getClassConstructIoc($className) {
if(!isset($this->classConstructIocs[$className])) {
$this->classConstructIocs[$className]=array(); if(in_array('__construct',get_class_methods($className))){
$mo=new ReflectionMethod ($className,'__construct');

foreach($mo->getParameters() as $parameter){
$po=new ReflectionParameter(array($className,'__construct'),$parameter->name);
$this->classConstructIocs[$className][$parameter->name]=$po->getClass()->name;
}
}
} return $this->classConstructIocs[$className];
}}$PHPiocContainer=new PHPiocContainer;
$PHPiocContainer->regClass('A');//注册的顺序没有关系
$PHPiocContainer->regClass('B');
$PHPiocContainer->regClass('C');$myC=$PHPiocContainer->getObject('C');
print_r($myC);

解决方案 »

  1.   

    改了下,支持派生类,这样类型指示才比较象一个
    //以下A/B/BB/BB/C 5个类,相互间有继承/依赖,通过构造函数注入 
    class  A{ 
    } abstract class B { 
    protected $o;  function __construct(A $o) { 
    $this->o=$o; 

    abstract function showName();
    } class BB extends B {
    function showName() {
    echo get_class($this),'::',__FUNCTION__;
    }
    }class BBB extends BB {
    function showName() {
    echo get_class($this),'::',__FUNCTION__;
    }
    }class C { 
    protected $o; 
    protected $oo;  function __construct(B $o,A $oo) { 
    $this->o=$o; 
    $this->oo=$oo; 
    }  function getOB() {
    Return $this->o;
    }
    }//测试的微核心容器类。没搞父子容器啥的。通过参数的类型指示/反射,创建对象时自动注入其依赖的其他对象 
    class PHPiocContainer { 
    protected $regClassNames=array(); 
    protected $classConstructIocs=array();  //注册类 
    public function regClass($className) { 
    $this->regClassNames[]=$className; 
    }  //返回对象 
    public function getObject($className) { 
    if(!in_array($className,$this->regClassNames)){
    exit('Class '.$className.' is not registered'); 
    }
    return $this->createObject($className); 
    }  //递归创建对象 
    protected function createObject($className) { 
    if(false==$newClassName=$this->getDerivedClass($className)){ 
    exit('Class '.$className.' is not registered'); 
    }  $p=array();  foreach($this->getClassConstructIoc($newClassName) as $hintClass){ 
    if(!empty($hintClass)){ 
    $p[]=$this->createObject($hintClass); 

    }  $newP='';
    for ($i = 0; $i < count($p); $i++) { 
    $newP .= '$p['.$i.'],'; 

    $newP = rtrim($newP,',');  return eval("return new $newClassName($newP);"); 
    }  //获得 类构造函数 其所有参数的类型指示 
    protected function &getClassConstructIoc($className) { 
    if(!isset($this->classConstructIocs[$className])) { 
    $this->classConstructIocs[$className]=array();  if(in_array('__construct',get_class_methods($className))){ 
    $mo=new ReflectionMethod ($className,'__construct');  foreach($mo->getParameters() as $parameter){ 
    $po=new ReflectionParameter(array($className,'__construct'),$parameter->name); 
    $this->classConstructIocs[$className][$parameter->name]=$po->getClass()->name; 


    }  return $this->classConstructIocs[$className]; 
    } //返回指示类型的派生类,或自己
    protected function getDerivedClass($hintClass) {
    if(class_exists($hintClass,false)==true){
    if(in_array($hintClass,$this->regClassNames)){
    $ho=new ReflectionClass ($hintClass);
    if($ho->isAbstract()!=true && $ho->isInterface()!=true){
    Return $hintClass;
    }
    } foreach($this->regClassNames as $regClassName){
    if($regClassName!=$hintClass){
    $so=new ReflectionClass ($regClassName);
    if(true==$so->isSubclassOf($hintClass) && $so->isAbstract()!=true && $so->isInterface()!=true) {
    Return $regClassName;
    }
    }
    }
    }else{
    exit('Class '.$hintClass.' does not exist'); 
    }

    Return false;
    }} $PHPiocContainer_1=new PHPiocContainer; 
    $PHPiocContainer_1->regClass('A');//注册的顺序没有关系 
    $PHPiocContainer_1->regClass('BBB'); //这里不一样
    $PHPiocContainer_1->regClass('C'); $myC=$PHPiocContainer_1->getObject('C'); 
    print_r($myC);
    echo $myC->getOB()->showName();
    echo "<br><br>\n\n";$PHPiocContainer_2=new PHPiocContainer; 
    $PHPiocContainer_2->regClass('A');//注册的顺序没有关系 
    $PHPiocContainer_2->regClass('BB');  //这里不一样
    $PHPiocContainer_2->regClass('C'); $myC=$PHPiocContainer_2->getObject('C'); 
    print_r($myC);
    echo $myC->getOB()->showName();
      

  2.   

     微核心容器 PicoContainer 是什么,上面不就是一个注册器嘛?