Laravel 依赖注入深入了解 门面模式 迭代器的使用 从零搭建laravel 框架

最近在学习 java  。 看java 入门到精通 。在反射部分 突然对以前不懂的 依赖注入 豁然开朗

依赖注入  就是通过反射 去获取对象中需要的参数 类

下面是模仿laravel 实现过程 。比较 low

 原创  转载请注明出处

https://github.com/Childdreams/laravelIoc 源码地址

register = array_merge($this->register , $bind) ;
    }
}



namespace cpp;
use app\interfaces\RequestInterface;
use app\interfaces\SendSmsInterface;

/**
 * 控制器
 */
class UserController
{
    public function __construct()
    {
    }

    public function test(RequestInterface $request , SendSmsInterface $sendSmsService){
        var_dump($request->id);
        var_dump("this is 依赖注入");
		var_dump($sendSmsService->name);
    }
}

namespace test;

use bpp\Container;

//实例化容器
$api = new Container();
//将依赖注册到容器  , 此处用 接口模式 是为了 解耦合
$api->register([
	\app\interfaces\RequestInterface::class => \app\Request::class
]);
$api->register([
	\app\interfaces\SendSmsInterface::class => \app\SendSmsService::class
]);

// 模仿路由
$router = "cpp\UserController@test";
$routers = explode("@",$router);

// 将 控制器 反射 出来
$ref = (new \ReflectionClass($routers[0]));

// 获取 控制器的 方法 里面的参数
$refs = $ref->getMethod($routers[1])->getParameters();

$inject = [];

foreach ($refs as $re){
	
	//获取参数的类
    $class = $re->getClass()->name;
	// 在容器查询 是否注册过
    if (array_key_exists($class , $api->register)){
		// 获取 容器内注册的方法
		$class = $api->register[$class];
		//浅显易懂
        $classes = $ref->newInstance();
        $name = $routers[1];
		$inject[] = new $class();
    }else {
		throw new \Exception("bug");
	}
}

(new $classes())->{$name}(...$inject);

依赖注入

  • 理解

    依赖注入的实现方式就是 将需要注入的服务注册到容器内, 当路由访问一个控制器的时候 利用反射ReflectionClass 去获取需要注入的服务。然后将服务进行实例化注入

    代码实现部分

    $router = "cpp\UserController@test";
    $routers = explode("@", $router);
    
    // 将 控制器 反射 出来
    
    $ref = (new \ReflectionClass($routers[0]));
    
    
    // 获取 控制器的 方法 里面的参数
    $refs = $ref->getMethod($routers[1])->getParameters();
    
    $inject = [];
    foreach ($refs as $re) {
      //获取参数的类
      $class = $re->getClass()->name;
      // 在容器查询 是否注册过
      if (array_key_exists($class, $app->register)) {
          // 获取 容器内注册的方法
          $class = $app->register[$class];
          //浅显易懂
          $name = $routers[1];
          $inject[] = new $class();
      } else {
          throw new \Exception("bug");
      }
    }
    $classes = $ref->newInstance();  // == new $ref
    call_user_func_array([$classes , $name] , ...$inject) ; 
    

    至于怎么注册到容器 laravel 的写法是 服务提供者。 将服务提供者注册到

    /config/app.php

    将服务提供者携带的 服务注册到 容器中 bootstrap/app.php line 23

    baofeng\Demo\Kernel\Kernel@reisterServiceProvider

门面模式

门面模式的核心内容 依旧是将门面模式的注入到容器之中 。在正常的 门面模式直接返回注入时候的key , 通过 __callstatic 去容器中查询

baofeng\Demo\Facaders\Facader

迭代器 IteratorAggregate

laravel 中 db 等 对象进行foreach 循环时候 ,循环出来的只是它想让你循环的东西 这时候就用到了

baofeng\Demo\Https\Request

baofeng\Demo\Iterators\MyIterator

详细的注释在 baofeng\Demo\Iterators\MyIterator 中

你可能感兴趣的:(PHP,laravel)