php的微核心容器 PHPiocContainer

testoktest 2009-11-12 12:39:39
最近正在搞对象依赖,除了配置文件,还有就是微核心容器 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);
...全文
220 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
babysc1 2009-11-12
  • 打赏
  • 举报
回复
学习~这东西不错
knight0450 2009-11-12
  • 打赏
  • 举报
回复
先顶再看~~
zlcqupt 2009-11-12
  • 打赏
  • 举报
回复
学习
zlcqupt 2009-11-12
  • 打赏
  • 举报
回复
学习
liuyang1588 2009-11-12
  • 打赏
  • 举报
回复
bu dong
jlzan1314 2009-11-12
  • 打赏
  • 举报
回复
微核心容器 PicoContainer 是什么,上面不就是一个注册器嘛?
testoktest 2009-11-12
  • 打赏
  • 举报
回复
改了下,支持派生类,这样类型指示才比较象一个




//以下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();

21,893

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧