Reference materials:
Explanation of the core concepts of laravel's underlying core code analysis
PHP Inversion of Control (IOC) and Dependency Injection (DI)
Closure anonymous functions, are you still confused?

Laravel framework core

advantage

  1. Integrated composer
  2. Realize dependency injection, better manage dependencies of classes, and facilitate expansion (compared to MVC mode)
  3. Advanced features: console, event event, queue queue, middleware, facade mode facades
  4. Core concept: service container serviceProvider

Disadvantages and optimization

shortcoming

  1. Too many files are loaded and the access speed is slow

optimization

  1. Cache configuration file
  2. Remove unnecessary loading files (mainly serviceProvider)
  3. Open Opcache

Framework startup process (life cycle)

  1. Reference auto-loading files
  2. Generate service container
    1) Register basic bingings
    2) Register service container, event, routing, log service through bind
    3) Bind the interface through bind
  3. Get the Request object
  4. Logical processing
    1) Analyze startup items (basic services) such as routing, exception handling, facade, service container
    2) Through the pipeline mode, use middleware to filter user requests and process business logic
  5. Return the Response object

Knowledge points

Singleton mode, observer mode, pipeline mode
Dependency injection, anonymous functions, reflection
Predefined interface ArrayAccess

Inversion of control and dependency injection

Inversion of control (IOC)

Manage the dependencies between components from the inside of the program to the outside

Explanation: Do not create a new instance of class B directly in class A, but pass the instance of class B to A through the IOC container

Dependency injection DI (dependency injection)

Inject component dependencies through external parameters or other forms

Example:

class DbMysql
{
    public function query(){}
}
class IOC
{
    public $db;
    public function __construct($dbMysql)
    {
        $this->db = $dbMysql;
    }
    public function action()
    {
        $this->db->query();
    }
}
$db = new DbMysql();
$c = new IOC($db);
$c->action();

In the IOC class, there is no need to instantiate DbMysql, but an instance of DbMysql is passed in as a parameter, and only the method of DbMysql is called. This mode is dependency injection .

Proposing the instantiation action of class B outside the IOC class is called inversion of control .

PHP's reflection mechanism

When PHP is running, the analysis program is extended to export or present detailed information about classes, methods, attributes, and parameters. This function of dynamically acquiring and invoking information is called reflection API.
class A 
{
    public function __construct(B $b)
    {
    }
}
class B 
{
}
//获取类的反射信息(所有信息)
$reflector = new ReflectionClass('A');
//获取构造函数
$constructor = $reflector->getConstructor();
//获取构造函数参数
$dependencies = $constructor->getParameters();
//获取依赖的类名
foreach ($dependencies as $dependency){
    if(!is_null($dependency->getClass())){
        $classname = $dependency->getClass()->name;
        $p[] = new $classname();
    }
}
//从给出的参数创建一个新的类实例
$a = $reflector->newInstanceArgs($p);

If class B also has dependent classes, it needs to be recursively created

<?php 
class A
{
    public function __construct(B $b)
    {
        $this->b = $b;
    }
    public function getB()
    {
        $this->b->bMethod();
    }
}
class B
{
    public function __construct(C $c,D $d)
    {
        $this->c = $c;
        $this->d = $d;
    }
    public  function bMethod()
    {
        echo "我是B中的方法bMethod()";
    }
}

class C{
    public function __construct()
    {
    }
    public function cMethod(){
        echo "我是C中的方法cMethod()";
    }
}

class D{
    public function __construct()
    {
    }
    public function dMethod(){
        echo "我是D中的方法dMethod()";
    }
}
class Ioc
{
    protected $instances = [];
    public function __construct()
    {
    }
    public function getInstance($classname){
        $reflector = new ReflectionClass($classname);
        $constructor = $reflector->getConstructor();
        $dependencies = $constructor->getParameters();
        if(!$dependencies){
            return new $classname();
        }
        foreach ($dependencies as $dependency){
            if(!is_null($dependency->getClass())){
                $instances[] = $this->make($dependency->getClass()->name);
            }
        }
        return $reflector->newInstanceArgs($instances);
    }
    public function make($classname){
        return $this->getInstance($classname);
    }
}
$ioc = new Ioc();
$a = $ioc->make('A');
$a->getB();

Summarize

The essence of running a PHP program: include files and get instantiated objects.
Traditional framework: Manage class dependencies through include/require.
Laravel: Through namespace and use, the automatic loading mechanism is realized, the file where the class is found, and then the instantiated object of the class is obtained through reflection.

Learning materials:
's underlying core code analysis 16183b6341eb6b
Closing anonymous functions, are you still confused?

Anonymous function

Callback

When calling a function, pass another function as a parameter to the called function, instead of passing an ordinary variable as a parameter

The callback function is used to pass a self-defined function to the function for use

function test($v){
    return $v * $v;
}
$a = array(1, 2, 3);
print_r(array_map("test", $a)); //[1, 4, 9]

Anonymous function

Functions without names are anonymous functions

1. Ordinary use

$func = function($str){
    echo $str;
};
$func('Hello');

2. Use use to pass external variables

$b = "World";
$func = function($str) use($b){
    echo $str. " ". $b;
};
$func("Hello");

Closures

Closure of php is also an anonymous function. It was introduced by PHP5.3.
Closure function is a function that can read the internal variables of other functions
Closure = anonymous function + use
function getMoney($a, $b){
    return function($p) use ($a, $b){
        echo $p. '-'. $a. '-'. $b;
    };
}
$closure = getMoney('1', '2');
var_dump($closure instanceof Closure);//true
$closure('test');//test-1-2

Practical application

1. As a callback function

src/Illuminate/Routing/Router.php
    public function gatherRouteMiddleware(Route $route)
    {
        $middleware = collect($route->gatherMiddleware())->map(function ($name) {
            return (array) MiddlewareNameResolver::resolve($name, $this->middleware, $this->middlewareGroups);
        })->flatten();

        return $this->sortMiddleware($middleware);
    }

2. As a closure

src/Illuminate/Container/Container.php
    //创建
    protected function getClosure($abstract, $concrete)
    {
        return function ($container, $parameters = []) use ($abstract, $concrete) {
            if ($abstract == $concrete) {
                return $container->build($concrete);
            }

            return $container->make($concrete, $parameters);
        };
    }
    //绑定
    function bind($abstract, $concrete = null, $shared = false)
    {
       ...
        if (! $concrete instanceof Closure) {
            $concrete = $this->getClosure($abstract, $concrete);
        }
        ...
    }
    //调用
    public function build($concrete)
    {
        if ($concrete instanceof Closure) {
            return $concrete($this, $this->getLastParameterOverride());
        }
        ...
    }

Precautions

1. Anonymous functions are only parsed when they are called
2. When calling an anonymous function, you need to pass the parameters behind the function

IT小马
1.2k 声望166 粉丝

Php - Go - Vue - 云原生