Laravel底层学习笔记01 - 框架核心,依赖注入,闭包

IT小马 -
Laravel底层学习笔记01 - 框架核心,依赖注入,闭包

参考资料:
laravel底层核心代码分析之核心概念讲解
PHP控制反转(IOC)和依赖注入(DI)
闭包匿名函数,还在傻傻搞不清楚吗?

Laravel框架核心优点集成了composer实现了依赖注入,更好的管理类的依赖关系,方便扩展(相对于MVC模式)高级特性:控制台console,事件event,队列queue,中间件middleware,门面模式facades核心概念:服务容器 serviceProvider缺点及优化缺点加载文件太多,访问速度慢优化缓存配置文件去掉不必要的加载文件(主要是serviceProvider)开启Opcache框架启动流程(生命周期)引用自动加载文件生成服务容器
1) 注册基础的bingings
2) 通过bind注册服务容器,事件,路由,日志服务
3) 通过bind绑定接口获取Request对象逻辑处理
1) 解析启动项(基础服务)如路由,异常处理,门面,服务容器
2) 通过管道模式,用中间件过滤用户请求,处理业务逻辑返回Response对象知识点单例模式,观察者模式,管道模式
依赖注入,匿名函数,反射
预定义接口ArrayAccess控制反转和依赖注入控制反转 IOC(inversion of control)将组件间的依赖关系从程序内部提到外部来管理

解释:不在A类中直接新建B类实例,而是通过IOC容器将B类的实例传给A

依赖注入 DI(dependency injection)将组件的依赖通过外部以参数或其他形式注入

示例:

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();

IOC类中不需要实例化DbMysql,而是将DbMysql的实例作为参数传入,仅调用DbMysql的方法。这种模式就是依赖注入

将B类的实例化动作提出到IOC类的外面,就叫做控制反转

PHP的反射机制在PHP运行时,扩展分析程序,导出或提出关于类,方法,属性,参数的详细信息,这种动态获取和调用信息的功能称为反射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);

如果B类也有依赖的类,则需要通过递归创建

<?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();
总结PHP程序运行的本质:包含文件,获取实例化对象。
传统框架:通过include/require来管理类的依赖关系。
Laravel:通过namespace和use,实现了自动加载机制,找到类所在文件,然后通过反射获取类的实例化对象。

学习资料:
laravel底层核心代码分析之匿名函数
闭包匿名函数,还在傻傻搞不清楚吗?

匿名函数回调函数

调用函数的时候将另一个函数作为参数传递到调用的函数中,而不是传递一个普通的变量作为参数

使用回调函数是为了可以将一段自己定义的功能传到函数内部使用

function test($v){
    return $v * $v;
}
$a = array(1, 2, 3);
print_r(array_map("test", $a)); //[1, 4, 9]
匿名函数没有名字的函数就是匿名函数1.普通使用
$func = function($str){
    echo $str;
};
$func('Hello');
2.使用use传递外部变量
$b = "World";
$func = function($str) use($b){
    echo $str. " ". $b;
};
$func("Hello");
闭包(closures)php的闭包(Closure)也就是匿名函数。是PHP5.3引入的。
闭包函数就是能够读取其他函数内部变量的函数
闭包 = 匿名函数 + 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
实际应用1. 当做回调函数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. 当做闭包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());
        }
        ...
    }
注意事项1. 匿名函数只有在调用的时候才会真正解析2. 调用匿名函数时需要传递function后面的参数
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

php介绍

PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。

Tags 标签

laravelphp

扩展阅读

加个好友,技术交流

1628738909466805.jpg