Laravel框架运行机制(四)实例化APP的运行过程

这篇具有很好参考价值的文章主要介绍了Laravel框架运行机制(四)实例化APP的运行过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

    看了一下Laravel框架对APP的实例化,确实与其它的框架完全不同。大量使用Closure,而且是一层又一层的Closure,之前已经写了一些对Laravel加载vendor的总结,这里写一下加载APP对象的结,Laravel执行到这步还只是实例化了APP对象,并未开始真正的业务操作,业务操作都在Kernel对象里,说说其它的几个框架的源代码吧:

ThinkPhp框架:代码一看就明白,可以这么说,TP框架就是用一堆面向过程的PHP程序堆成了一个功能也不错、使用也方便的框架。

Codeigniter框架:Php框架的起源,初始化各种类然后导入到APP类中,然后在框架里使用$this->db等来操作一切所需要的类,简单,但大道至简吧。

Yii框架:我已经很久没看过YII了,1.1时代看过,那时也没看透,但YII我一直觉得很强大。底层基本无明显缺陷,功能齐全。GII功能没有框架可比。

Laravel框架:非常新,框架的加载过程非常新颖。和其它的框架都很不相同。毕竟Laravel起点很高,起点要求PHP5.4,大量使用新特性。

    看一下laravel框架index.php执行完vendor之后加载app.php的代码:

//index.php中执行加载app.php
$app = require_once __DIR__.'/../bootstrap/app.php';

//bootstrap/app.php文件中执行对app的操作
$app = new IlluminateFoundationApplication(
    realpath(__DIR__.'/../')
);
$app->singleton(
    IlluminateContractsHttpKernel::class,
    AppHttpKernel::class
);
$app->singleton(
    IlluminateContractsConsoleKernel::class,
    AppConsoleKernel::class
);
$app->singleton(
    IlluminateContractsDebugExceptionHandler::class,
    AppExceptionsHandler::class
);
return $app;

    初始化IlluminateFoundationApplication类并传入laravel整体根目录路径。就调用到了vendor/laravel/framework/src/Illuminate/Foundation/Application.php类,这个类文件初始化的过程中主要操作了三个方法:如下:

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

     registerBaseBindings方法处理简单,只是把Application类的静态属性$instance、还有数组属性instances的app键值初始化递归成本类,

    registerBaseServiceProviders方法则比较复杂,执行了$this->register(new EventServiceProvider($this));和$this->register(new RoutingServiceProvider($this));两个方法,分别是注册基础events服务和路由等其它服务组件,$this->register(new EventServiceProvider($this));方法所调用的整个过程最重要的在文件:laravel/vendor/laravel/framework/src/Illuminate/Foundation/Application.php文件约545行里执行的这句:

$provider->register();

    而上面这句代码调用的方法执行的是调用Application的singleton方法,将events注册到Application的数组属性bindlings里,如下:

public function register()
{
	$this->app->singleton('events', function ($app) {
		return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
			return $app->make('IlluminateContractsQueueFactory');
		});
	});
}

     上面的代码:(暂时先不要去理会function($app)这个闭包函数的处理,直接看vendor/laravel/framework/src/Illuminate/Container/Container.php中的singleton方法),会调用singleton方法,实际是调用Container.php的bind方法:public function bind($abstract, $concrete = null, $shared = false);并固定传参shared为true。bind方法里两句很重要的代码:

if (! $concrete instanceof Closure) {
	$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');

    判断入参$concrete是否是闭包函数,Laravel里所有bind的对象全部要求是闭包函数,如果不是就调用getClosure方法造成闭包函数,方法如下:

protected function getClosure($abstract, $concrete)
{
	return function ($c, $parameters = []) use ($abstract, $concrete) {
		$method = ($abstract == $concrete) ? 'build' : 'make';
		return $c->$method($concrete, $parameters);
	};
}

    可见,如果传入的不是闭包函数,就会将他们转化成一个闭包函数的参数,在闭包函数中通过build或者make方法去调用。注意,$provider->register()这步看起来是执行$provider的方法,实际上是执行Application的方法,并修改Application实例的属性。这样执行后,Application类的bindlings数组属性值就成了如下图:

Laravel框架运行机制(四)实例化APP的运行过程,后端PHP开发,laravel,php

    可以看到bindlings下的组件都要相同的结构,都是由一个闭包函数组件以及是否共享两个组成,而闭包函数组件看似是相同的结构,实际可以根据其中闭包函数调用的不同的类完成的不同的功能。到这里看的都是laravel/vendor/laravel/framework/src/Illuminate/Foundation/Application.php约545行里执行的这句$provider->register();所执行的功能,而更精妙的这句代码在其后:

$this->markAsRegistered($provider);

     此方法的执行程序如下:

 

protected function markAsRegistered($provider)
{
	$this['events']->fire($class = get_class($provider), [$provider]);
	$this->serviceProviders[] = $provider;
	$this->loadedProviders[$class] = true;
}

     几个字码的代码:$this['events'],这里实际上是使用对象数组式访问ArrayAccess的方法,执行了很重要的功能,最终调用了类:vendor/laravel/framework/src/Illuminate/Container/Container.php的offsetGet方法,然后offsetGet里再去调用Container里的make方法来,而在make方法里再调用getConcrete取出bindlings下面events数组里的concrete(如上面的图),这是laravel所有调用make时的操作,就是取出其闭包函数。取出闭包函数后会执行:

if ($this->isBuildable($concrete, $abstract)) {
	$object = $this->build($concrete, $parameters);
} else {
	$object = $this->make($concrete, $parameters);
}

     isBuildable方法,只要concrere是闭包函数就会执行,所以此处会再调用build方法,而build方法实际就是执行这个闭包函数,代码如下:

public function build($concrete, array $parameters = [])
    {
        if ($concrete instanceof Closure) {
            return $concrete($this, $parameters);
        }
...
}

     至此实际完成的功能就是在Application类里的instances数组属性值里添加了一个events闭包函数执行后的组件,此处调用的events执行完后,instances数组数据即:IlluminateEventsDispatcher Object如下:

Laravel框架运行机制(四)实例化APP的运行过程,后端PHP开发,laravel,php

    为什么是这个对象,我们可以回头看到在最开始调用$this->register(new EventServiceProvider($this));时实例化的new 类vendor/laravel/framework/src/Illuminate/Events/EventServiceProvider.php中的register方法里执行的是:

return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
                return $app->make('IlluminateContractsQueueFactory');
            });

    所以最终通过$this['events']这个看起来很简单的索引,实际后面完成了组件注册后的实例化。Laravel的Application干的工作就是这样,注册服务组件到Application属性bindings:protected中,而且所有的组件都是一个闭包函数,然后根据需要使用数组索引一下就完成了这个组件的实例化,并写入到数组属性值:instances中。执行完这句后,后面Application的实例化代码功能也都一样了:

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

    上面的第一句代码注册了一些基础服务(比如router,url,redirect等),而registerCoreContainerAliases则是加载了一些类的别名。至此Application类完成了实例化。之后便是Kernel使用Application来创建AppHttpKernel对象,并通过此对象的handle方法来处理请求对象Request,以返回处理结果。文章来源地址https://www.toymoban.com/news/detail-851373.html

到了这里,关于Laravel框架运行机制(四)实例化APP的运行过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【PHP系统学习】——Laravel框架数据库的连接以及数据库的增删改查的详细教程

    👨‍💻个人主页 :@开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏 :PHP程序开发 —   按照 MVC 的架构,对数据的操作应该放在 Model 中完成,但如果不使用 Model,我们也可以用 laravel框架提供的 D8 类

    2024年04月15日
    浏览(50)
  • RabbitMQ运行机制和通讯过程介绍

    参考我的另一篇:RabbitMQ安装及使用教程(最全版)常用语令_Elaine猿的博客-CSDN博客   RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在不同的应用之间共享数据(跨平台跨语言)。RabbitMQ是使用Erlang语言编写,并且基于AMQP协议实现。 技术知识背景介绍: AMQ

    2024年02月07日
    浏览(37)
  • golang iris框架 + linux后端运行

    打包应用 开启服务 关闭后台 杀死进程 通过 ps -ef|grep main 找到应用出现 找到应用的( PID(一般是第一个数字) )

    2024年02月07日
    浏览(56)
  • 第010天:APP在后台的运行机制

            记得在我上大学的时候,iPhone 是属于少数人才拥有的稀有物品, Android 甚至还没面世,那个时候全球的手机市场是由诺基亚统治着的。当时我觉得诺基亚的 Symbian 操作系统做得特别出色,因为比起一般的手机,它可以支持后台功能。那个时候能够一边打着电话、

    2023年04月14日
    浏览(81)
  • 机器学习分布式框架ray运行xgboost实例

            Ray是一个开源的分布式计算框架,专门用于构建高性能的机器学习和深度学习应用程序。它的目标是简化分布式计算的复杂性,使得用户能够轻松地将任务并行化并在多台机器上运行,以加速训练和推理的速度。Ray的主要特点包括支持分布式任务执行、Actor模型、

    2024年02月15日
    浏览(46)
  • 不走弯路!记一个Appium框架运行的实例

    目录        前言: 一、框架环境安装 二、测试流程操作 1、安装APK 2、启动 3、服务参数配置 4、脚本录制操作 5、脚本编写 6、脚本执行 三、测试总结              Appium是一个开源的自动化测试框架,用于移动应用程序的自动化测试。它支持在iOS和Android平台上进行原生

    2024年02月10日
    浏览(47)
  • 机器学习分布式框架ray运行TensorFlow实例

    使用Ray来实现TensorFlow的训练是一种并行化和分布式的方法,它可以有效地加速大规模数据集上的深度学习模型的训练过程。Ray是一个高性能、分布式计算框架,可以在集群上进行任务并行化和数据并行化,从而提高训练速度和可扩展性。 以下是实现TensorFlow训练的概括性描述

    2024年02月15日
    浏览(52)
  • 2023最新多功能XL软件库APP源码+PHP后端系统源码/功能强大/软件库自带后台管理系统

    2023最新多功能XL软件库APP源码+PHP后端系统源码/功能强大/软件库自带后台管理系统31xl软件库最新可以正常使用版: https://url11.ctfile.com/d/25976711-57801726-b66bb0?p=6724 (访问密码:6724) 多功能软件库,支持自定义对接易支付   安装教程:   先导入sql数据库,然后修改config.php 里边填

    2024年02月10日
    浏览(64)
  • 华为云云耀云服务器L实例评测|用PHP从数据库到后端到前端完整实现一个中秋节祝福语项目

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于PHP专栏:PHP进阶实战教程,评测专区。 🎉欢迎 👍点赞✍

    2024年02月08日
    浏览(59)
  • 新版开源UI千月影视APP源码/后端基于ThinkPHP框架/前后端完美匹配

    源码简介: 开源UI千月影视APP源码,它是基于ThinkPHP框架,而且前后端完美匹配。这是一个广泛使用的PHP开发框架,具有稳定性和安全性方面的优势。 2023版本UI千月影视APP是一款提供电影、电视剧、综艺节目等视频内容的应用程序,用户可以通过它浏览、搜索和观看各种影视

    2024年02月06日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包