Laravel static binding and container principle

Time:2021-11-30

1、 Static binding in PHP

“Late binding” means that static:: is no longer resolved to the class that defines the current method, but is calculated at the actual run time. It can also be called “static binding” because it can be used for (but not limited to) calls to static methods.

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); //  Later static binding starts here
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();// The result is B
?>

To put it bluntly, which class calls a static method, the static method belongs to which class.

2、 Static binding in laravel
In laravel, app () can be used to instantiate a container, and then the container is single, which operates laravel’s various providers, events, etc. Code trace to see the principle of its container implementation;
First look at the app () method. Helpers.php is the portal file that has been loaded into the framework;
\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php

 function app($abstract = null, array $parameters = [])
    {
        if (is_null($abstract)) {
            return Container::getInstance();
        }

        return Container::getInstance()->make($abstract, $parameters);
    }

From the above code, we can see that it mainly runs the static method getInstance of the container class.

Let’s trace from the entry file public / index.php to see where there is setinstance,

$app = require_once __DIR__.'/../bootstrap/app.php';

bootstrap/app.php

//Instantiate a container, which is the core of laravel. Use this to constantly call the inner part of laravl
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

\vendor\laravel\framework\src\Illuminate\Foundation\Application.php
Let’s look at inheritance first

class Application extends Container implements ApplicationContract, CachesConfiguration, CachesRoutes, HttpKernelInterface

Then constructor

public function __construct($basePath = null)
    {
        if ($basePath) {
            $this->setBasePath($basePath);
        }

        $this->registerBaseBindings();
        $this->registerBaseServiceProviders();
        $this->registerCoreContainerAliases();
    }

Basic binding $this – > registerbase bindings();

protected function registerBaseBindings()
    {
        static::setInstance($this);// The parent class is a static method. The parent class here is container

        $this->instance('app', $this);

        $this->instance(Container::class, $this);
        $this->singleton(Mix::class);

        $this->singleton(PackageManifest::class, function () {
            return new PackageManifest(
                new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
            );
        });
    }

View vendor \ laravel \ framework \ SRC \ illuminate \ container \ container.php

 public static function setInstance(ContainerContract $container = null)
    {
        return static::$instance = $container;
    }

See here, take a look at the getInstance method in this file

public static function getInstance()
    {
        if (is_null(static::$instance)) {
            static::$instance = new static;// Instantiate application
        }

        return static::$instance;
    }

From here, the whole container instantiation process of laravl is completed. It mainly relies on the static binding method to strengthen the application.

Recommended Today

On the mutation mechanism of Clickhouse (with source code analysis)

Recently studied a bit of CH code.I found an interesting word, mutation.The word Google has the meaning of mutation, but more relevant articles translate this as “revision”. The previous article analyzed background_ pool_ Size parameter.This parameter is related to the background asynchronous worker pool merge.The asynchronous merge and mutation work in Clickhouse kernel is completed […]