PHP's own framework 2.0 combined with container technology (Refactoring Part 2)

Table of contents

1. Use containers to implement framework loading classes and run them

2. Create the framework container class core/fm/Di.php

3. The framework uses the container class to execute public/index.php

4. The operating effect is still the same


1. Use containers to implement framework loading classes and run them

2. Create the framework container class core/fm/Di.php

What is a container? A container is equivalent to a box. You can put many classes inside and reuse them to prevent multiple instantiations, save resources, etc.

<?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. The framework uses the container class to execute 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. The operating effect is still the same

Guess you like

Origin blog.csdn.net/weixin_39934453/article/details/132842443