PHP自己的框架2.0结合容器技术(重构篇二)

目录

1、使用容器实现框架加载类运行

2、 创建框架容器类core/fm/Di.php

3、框架使用容器类来执行public/index.php

4、运行效果还是一样


1、使用容器实现框架加载类运行

2、 创建框架容器类core/fm/Di.php

什么是容器?容器就相当于盒子,把很多类放里面,重复利用,防止多次实例化,节约资源等

<?php
namespace fm;
use ArrayAccess;

class Di implements ArrayAccess{
    protected static $instance;
    protected $instances = [];//已实例化类
    protected  $bind=[
        'core'=>core::class,
    ];//服务列表

    //单例模式 防止多次new
    public static function getInstance(){
        if(self::$instance){
            return self::$instance;
        }
        static::$instance = new static;
        return static::$instance ;

    }
    //获取实例化类
    public static function get($abstract, $vars = []){

        return static::getInstance()->make($abstract, $vars = []);
    }
    //获取类库
    public function make($abstract, $vars = []){

        //先从已经实例化的列表中查找

        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }

        //检测有没有注册该服务

        if(!isset($this->bind[$abstract])){
            return null;
        }
        $concrete = $this->bind[$abstract];//对象具体注册内容
        $obj = null;
        //匿名函数方式

        if($concrete instanceof \Closure){
            $obj = call_user_func_array($concrete,$vars);
        }elseif(is_string($concrete)){//字符串方式
            if(empty($vars)){
                $obj = new $concrete;
            }else{
                //带参数的类实例化,使用反射
                $class = new \ReflectionClass($concrete);
                $obj = $class->newInstanceArgs($vars);
            }
        }

        return $obj;
    }
    public function bindTo($abstract, $concrete = null)
    {
        if (is_array($abstract)) {
            $this->bind = array_merge($this->bind, $abstract);
        } elseif ($concrete instanceof Closure) {
            $this->bind[$abstract] = $concrete;
        } elseif (is_object($concrete)) {
            if (isset($this->bind[$abstract])) {
                $abstract = $this->bind[$abstract];
            }
            $this->instances[$abstract] = $concrete;
        } else {
            $this->bind[$abstract] = $concrete;
        }

        return $this;
    }
    //检测是否已经绑定
    public function has($abstract){
        return isset($this->bind[$abstract]) || isset($this->instances[$abstract]);
    }

    //卸载服务
    public function remove($abstract){
        return static::getInstance()->delete($abstract);
    }
    public function delete($abstract)
    {
        unset($this->instances[$abstract]);
    }

    //继承接口必要继承方法
    public function offsetExists($offset) {
        return $this->has($offset);
    }
    public function offsetGet($offset) {
        return $this->make($offset);
    }
    public function offsetSet($offset, $value) {
        $this->bindTo($offset, $value);
    }
    public function offsetUnset($offset) {
        return $this->remove($offset);
    }
    public function getIterator() {
        return new ArrayIterator($this->instances);
    }
    public function count() {
        return count($this->instances);
    }


}

3、框架使用容器类来执行public/index.php
<?php
namespace fm;
error_reporting(E_ALL);
ini_set('display_errors', 'On');
// 加载基础文件
require __DIR__ . '/../core/base.php';
Di::get('core')->run();
4、运行效果还是一样

猜你喜欢

转载自blog.csdn.net/weixin_39934453/article/details/132842443