美文网首页
手写一个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