php 服务容器的问题

manbudezhu 发布于 2017/03/23 12:09
阅读 345
收藏 1

最近开始学习larval的服务容器 ,根据网上的教程,写的服务容器类如下.

有一个问题,我想访问使用静态的方式调用非静态的方法.
如下面调用中$foo->doSomething();写作$foo::doSomething().我看到网上的思路是使用__callstatic指向一个真实的对象,该怎么改写下面的容器Container类了.谢谢

 

<?php
/******************基础类********************/
class Bim
{
	public function doSomething()
	{
		echo __METHOD__, '|';
	}
}

class Bar
{
	private $bim;

	public function __construct(Bim $bim)
	{
		$this->bim = $bim;
	}

	public function doSomething()
	{
		$this->bim->doSomething();
		echo __METHOD__, '|';
	}
}

class Foo
{
	private $bar;

	public function __construct(Bar $bar)
	{
		$this->bar = $bar;
	}

	public function doSomething()
	{
		$this->bar->doSomething();
		echo __METHOD__;
	}
}

/***************IoC容器*******************/
class Container
{
	//注册属性(数组)
	private $s = array();
	public function __set($k, $c)
	{
		echo 'i am set-->';
		$this->s[$k] = $c;
		var_dump($this->s);
	}

	public function __get($k)
	{
		echo "i am get-->";
        // return $this->s[$k]($this);
		return $this->build($this->s[$k]);
	}

    /**
     * 自动绑定(Autowiring)自动解析(Automatic Resolution)
     *
     * @param string $className
     * @return object
     * @throws Exception
     */
    public function build($className)
    {
    	echo "i am build-->";
        // 如果是匿名函数(Anonymous functions),也叫闭包函数(closures)
    	if ($className instanceof Closure) {
            // 执行闭包函数,并将结果
    		return $className($this);
    	}

    	/** @var ReflectionClass $reflector */
    	$reflector = new ReflectionClass($className);

        // 检查类是否可实例化, 排除抽象类abstract和对象接口interface
    	if (!$reflector->isInstantiable()) {
    		throw new Exception("Can't instantiate this.");
    	}

    	/** @var ReflectionMethod $constructor 获取类的构造函数 */
    	$constructor = $reflector->getConstructor();

        // 若无构造函数,直接实例化并返回
    	if (is_null($constructor)) {
    		return new $className;
    	}

        // 取构造函数参数,通过 ReflectionParameter 数组返回参数列表
    	$parameters = $constructor->getParameters();
        // 递归解析构造函数的参数
    	$dependencies = $this->getDependencies($parameters);

        // 创建一个类的新实例,给出的参数将传递到类的构造函数。
    	return $reflector->newInstanceArgs($dependencies);
    }

    /**
     * @param array $parameters
     * @return array
     * @throws Exception
     */
    public function getDependencies($parameters)
    {
    	echo "i am getDependencies-->";
    	$dependencies = [];
    	/** @var ReflectionParameter $parameter */
    	foreach ($parameters as $parameter) {
    		/** @var ReflectionClass $dependency */
    		$dependency = $parameter->getClass();
    		var_dump($dependency);
    		if (is_null($dependency)) {
                // 是变量,有默认值则设置默认值
    			$dependencies[] = $this->resolveNonClass($parameter);
    		} else {
                // 是一个类,递归解析
    			$dependencies[] = $this->build($dependency->name);
    		}
    	}

    	return $dependencies;
    }

    /**
     * @param ReflectionParameter $parameter
     * @return mixed
     * @throws Exception
     */
    public function resolveNonClass($parameter)
    {
        echo "i am resolveNonClass-->";
        // 有默认值则返回默认值
    	if ($parameter->isDefaultValueAvailable()) {
    		return $parameter->getDefaultValue();
    	}

    	throw new Exception('I have no idea what to do here.');
    }
}

/**************调用过程****************/

$di = new Container();

$di->foo = 'Foo';

/** @var Foo $foo */
$foo = $di->foo;

var_dump($foo);
$foo->doSomething();

 

加载中
返回顶部
顶部