php中var_dump() 打印出一個對象的時候,信息怎么看?


php 的一個依賴注入容器, 說白了,就是用php 的反射類,來在運行的時候動態的分析類具有的函數,以及動態分析函數的參數, 從而實例化類,並執行類的方法。

另外,php 中的 typehint 還是很有用的,反射的時候就有用到! 

 

 

 

 

 下面貼出代碼:

<?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__;
    }
}

class Container
{
    private $s = array();

    public function __set($k, $c)
    {
        $this->s[$k] = $c;
    }

    public function __get($k)
    {
        // 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 "<pre>";var_dump($className);
        // 如果是匿名函數(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)
    {
        $dependencies = [];

        /** @var ReflectionParameter $parameter */
        foreach ($parameters as $parameter) {
            /** @var ReflectionClass $dependency */
            $dependency = $parameter->getClass();
            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)
    {
        // 有默認值則返回默認值
        if ($parameter->isDefaultValueAvailable()) {
            return $parameter->getDefaultValue();
        }

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

// ----
//$c = new Container();
//$c->bar = 'Bar';
//$c->foo = function ($c) {
//    return new Foo($c->bar);
//};
//// 從容器中取得Foo
//$foo = $c->foo;
//$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething

///*// ----
$di = new Container();
//
$di->foo = 'Foo';
//
///** @var Foo $foo */
$foo = $di->foo;
//
var_dump($foo);exit;
echo "<pre>";var_dump($foo->doSomething());

var_dump( get_class($foo));
die();
///*
//Foo#10 (1) {
//  private $bar =>
//  class Bar#14 (1) {
//    private $bim =>
//    class Bim#16 (0) {
//    }
//  }
//}
//*/
//
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething*/

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM