美文网首页
手写一个laravel(一)容器实现

手写一个laravel(一)容器实现

作者: mafa1993 | 来源:发表于2020-11-15 16:17 被阅读0次

容器

  1. 容器
    • ioc,控制反转,控制了对象穿件,反转了创建对象的过程,原来是使用new 手动穿件对象,现在。不由自己创建,由ioc容器创建
      • 创建: 自己创建new
      • 反转:通过容器提供
    • di,依赖注入,只要由内部产生(如在构造函数中初始化,或者在类中使用)都不是依赖注入, 就是类从外部传入,通过IOC容器提供创建的实例,注入其运行所需要的的资源,依赖注入是ioc容器的实现
    • 解耦,ioc和di可以减少耦合
<?php

class A {
    public function __construct(){
        //工厂模式
        $factory = new Factory();
        $factory->getClass('xx','xx');
    }
    public function b(B $b){
        
    }
}

$b = new B();
$a = new A();
$a->b($b);  //此为最简单依赖注入

/* 
 * 原来实例化10个类,需要在类内部写10个实例化操作
 * 工厂模式: 通过传递的参数,返回创建的对象,需要实例化工厂类
 * IOC容器:控制实例创建, 
 **/


  1. 生命周期

composer包初始化,实现laravel容器

  1. composer init
    • 需要写包名
    • 描述,可以为空
    • 作者
  2. 创建src目录,增加autoload配置
  3. composer install 生成自动加载文件
{
    "name": "mfx/slaravel",
    "minimum-stability": "dev",
    "require": {},
    "autoload":{
        "psr-4":{
            "Slaravel\\":"src"
        }
    }
}
  1. 创建index.php 引入autoload
  2. 创建Test类,测试命名空间
  3. 创建Container类,创建bind,make singleton方法,实现容器
  4. 绑定接口
    • 接口可以起到约束作用,可以提前知道方法的参数及返回值

主要是实现bind() 绑定 singleton()单利绑定 instance()绑定实例 make()解析 remove()移除绑定 五个方法,源码见个人git https://github.com/mafa1993/slaravel

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/11/9 0009
 * Time: 20:43
 */

namespace Slaravel\Container;

// 容器,主要用于存储服务
// 主要包含两个方法,bind和make
class Container
{
    //容器绑定后存储在数组中
    protected $bindings = [];

    //存储共享容易,即使用singleton 绑定的实例
    protected $instances = [];

    /**
     * 注入,简单绑定实现
     * @param string $abstract 标识,绑定后的类名
     * @param mixed $concrete 对象或者回调,具体绑定那个对象,可以使回调,必报,字符串
     * @param bool $shared
     */
    public function bind($abstract,$concrete = null,$shared = false){
        //将对象存储起来,即为绑定,使用时在数组种查找
        //$this->bindings[$abstract] = $concrete;
        $this->bindings[$abstract]['shared'] = $shared;
        $this->bindings[$abstract]['concrete'] = $concrete;
    }

    /**
     *
     */
    public function getBind(){
        var_dump($this->bindings);
    }

    /**
     * 根据标识,将容器中对应的类解析出来使用,即为创建对象
     * @param string $abstract 标识
     * @param array $arguments 创建对象时的参数
     * @return Object
     */
    public function make($abstract,$arguments = [])
    {
        //判断标识是否存在
        if(!isset($this->bindings[$abstract]) and !isset($this->instances[$abstract])){
            exit('标识不存在,没有进行注册');
        }

        //判断是否是单利注册,即在instances是否存在
        if($this->instances[$abstract]){
            return $this->instances[$abstract];
        }

        $obj = $this->bindings[$abstract]['concrete'];
        //判断是否是闭包, Closure为闭包
        if ($obj instanceof \Closure){
            $obj =  $obj();
        }

        if (!is_object($obj)){
            $obj = new $obj(...$arguments);
        }


        if($this->bindings[$abstract]['shared']){
            $this->instances[$abstract] = $obj;
        }

        return $obj;
    }

    /**
     * 只实例化一次
     * @param string $abstract 标识,绑定后的类名
     * @param mixed $concrete 对象或者回调,具体绑定那个对象,可以使回调,必报,字符串
     * @param bool $shared
     */
    public function singleton($abstract,$concrete = null ,$shared = true){
        $this->bind($abstract,$concrete,$shared);
    }

    /**
     * 绑定实例到容器
     * @param $abstract string 标识
     * @param $instance object 实例化后的对象
     */
    public function instance($abstract,$instance){
        //将bindings中的清除,instances中存在的话,防止在bindings中还存了一份
        $this->removeBindings($abstract);
        $this->instances[$abstract] = $instance;

        //测试app是否成功注册
        var_dump($this->instances);
    }

    /**
     * 清除绑定的容器
     * @param string $abstract 要清除的标识
     */
    public function removeBindings($abstract){
        if(isset($this->bindings[$abstract])){
            unset($this->bindings[$abstract]);
        }
    }

}

相关文章

网友评论

      本文标题:手写一个laravel(一)容器实现

      本文链接:https://www.haomeiwen.com/subject/dwbnbktx.html