DIY implementation of ThinkPHP core framework (IX) container class

Time:2021-1-22

ThinkPHPContainerClass provides static methodsget()The instance can be obtained according to the class name or the alias of the class. The created instance will be kept to avoid repeated creation. Next, implement this method and modify itContainer.php, add the following code.

//* ThinkPHP 5 and 6 have the same parameters here
//     * @param string $abstract
//     * @param array $vars
//     * @param bool $newInstance
//     */
    public static function get(string $abstract, array $vars = [], bool $newInstance = false)
    {
        return static::getInstance()->make($abstract, $vars, $newInstance);
    }

to writegetInstance()Method, and add static properties$instanceSave your own instance.

protected static $instance;

public static function getInstance()
    {
        //Create your own instance
        if (is_null(static::$instance)) {
            static::$instance = new static;
        }
        return static::$instance;
    }

to writemake()method.

public function make (string $abstract, array $vars = [], bool $newInstance = false)
    {
        //The $Abstract here is the class name that contains the namespace
        if (isset($this->bind[$abstract])) {
            $abstract = $this->bind[$abstract];
        }

        //If it has been instantiated, return directly
        if (isset($this->instances[$abstract]) && !$newInstance) {
            return $this->instances[$abstract];
        }

        //If so, create it
        $object = $this->invokeClass($abstract, $vars);

        //Save instance
        if (!$newInstance) {
        $this->instances[$abstract] = $object;
        }

        return $object;
    }

Create an alias array to save properties$bind

    protected $bind = [
        'app' => App::class,
        'config' => Config::class,
        'request' => Request::class
    ];

to writeinvokeClass()method

public function invokeClass (string $class, array $vars = [])
    {
        //$vars is the parameter of the constructor
        return new $class();
    }

Modify entry fileindex.php

require __DIR__ . '/../core/base.php';
use think\Request;

$req = \think\Container::get('request');
var_dump($req instanceof Request);

Output bool (true) representationget()Methods the function was normal.

You can also use magic__get()and__set()To realize the direct operation of container instances by external objects.

    public function __get($abstract)
    {
        //Returns the class instance of the container
        return $this->make($abstract);
    }

public function __set($abstract, $instance)
    {
        if (isset($this->bind[$abstract])) {
            $abstract = $this->bind[$abstract];
        }
        //Load the container
        $this->instances[$abstract] = $instance;
    }

stayindex.phpTest

$container = \think\Container::getInstance();
//Get the instance in the container and output the object
var_dump($container->request);

//Load the container
$container->contianerName = $container;
var_dump($container->contianerName);

The output object (think / request) indicates success

This work adoptsCC agreementReprint must indicate the author and the link of this article