前言

本文主要给大家介绍了关于Laravel中Facade加载过程与原理的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
简介
Facades(读音:/fəˈsäd/ )为应用程序的 服务容器 中可用的类提供了一个「静态」接口。你不必 use 一大串的命名空间,也不用实例化对象,就能访问对象的具体方法。
use Config;
class Test
{
public function index()
{
return Config::get('app.name');
}
}
Facade 的启动与注册
Facade 的启动引导是在 Illuminate\Foundation\Bootstrap\RegisterFacades 中注册的。
public function bootstrap(Application $app)
{
Facade::clearResolvedInstances();
Facade::setFacadeApplication($app);
AliasLoader::getInstance(array_merge(
$app->make('config')->get('app.aliases', []),
$app->make(PackageManifest::class)->aliases()
))->register();
}
默认的别名配置是从 app 配置文件下的 aliases 读取的,PackageManifest 是 laravel 5.5 新增的 包自动发现 规则,这里我们暂时不考虑 PackageManifest 包提供的别名。
其中,array_merge 返回如下格式的数组:
"App" => "Illuminate\Support\Facades\App" "Artisan" => "Illuminate\Support\Facades\Artisan" "Auth" => "Illuminate\Support\Facades\Auth" "Blade" => "Illuminate\Support\Facades\Blade" ...
上面代码将通过 AliasLoader 把所有的 facade 注册进自动加载。其核心就是 php 的 spl_autoload_register。
/**
* Prepend the load method to the auto-loader stack.
*
* @return void
*/
protected function register()
{
if (! $this->registered) {
spl_autoload_register([$this, 'load'], true, true);
$this->registered = true;
}
}
注册完成后,后续所有 use 的类都将通过 load 函数来完成类的自动加载。
注意:这里在定义 spl_autoload_register 时,最后面的参数传的是 true。当该参数是 true 时,spl_autoload_register() 会添加函数到队列之首,而不是队列尾部。(优先通过该函数来完成自动加载)
也就是说,
<?php
use Config;
use App\User;
class Test
{
public function index()
{
Config::get('app.name');
new User();
}
}
不管我们 use 的是具体存在的类(App\User)还是别名 (Config),都将最先通过 load 函数来完成自动加载,当该函数返回 false 时,再由其他自动加载函数来完成自动加载(如 composer psr-4)。
在 AliasLoader 的 load 方法中,主要是用了 class_alias 函数来实现的别名自动加载。
public function load($alias)
{
if (isset($this->aliases[$alias])) {
return class_alias($this->aliases[$alias], $alias);
}
}
关于 class_alias 这里帖一个官方的列子:
class foo { }
class_alias('foo', 'bar');
$a = new foo;
$b = new bar;
// the objects are the same
var_dump($a == $b, $a === $b); //true
var_dump($a instanceof $b); //false
// the classes are the same
var_dump($a instanceof foo); //true
var_dump($a instanceof bar); //true
var_dump($b instanceof foo); //true
var_dump($b instanceof bar); //true
Facade 的加载
当我们在使用 Facade 时,如:
<?php
use Config;
class Test
{
public function index()
{
Config::get('app.name');
}
}
实际上加载的是 Illuminate\Support\Facades\Config 类(因为我们已经注册了 class_alias),相当于:
<?php
use Illuminate\Support\Facades\Config;
class Test
{
public function index()
{
Config::get('app.name');
}
}
而所有的 Facade 都继承自 Illuminate\Support\Facades\Facade 类,在该基类中定义了一个 __callStatic 方法,已至于我们能够轻松地使用 Facade(不用实列化)。
<?php
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
getFacadeRoot 方法用于获取别名类的具体实列,我们知道,所有的 Facade 类都需要定义一个 getFacadeAccessor 方法。该方法可能的返回值有:
如 Config Facade 的 getFacadeAccessor 方法如下:
protected static function getFacadeAccessor()
{
return 'config';
}
getFacadeRoot 方法将根据 getFacadeAccessor() 的返回值,从容器从取出对应的实列对象。
public static function getFacadeRoot()
{
$name = static::getFacadeAccessor();
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
由于 APP 容器中已经注册过 config 的实列
<?php
//Illuminate\Foundation\Bootstrap/LoadConfiguration
$app->instance('config', $config = new Repository($items));
所以 \Config::get('app.name', 'dafault) 实际访问的是 Repository 实列的 get('app.name', 'default') 方法。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# laravel
# facade
# 原理
# 设置
# 跟我学Laravel之请求(Request)的生命周期
# Laravel 5框架学习之模型、控制器、视图基础流程
# 跟我学Laravel之请求与输入
# Laravel 5.5中为响应请求提供的可响应接口详解
# Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
# Laravel中间件实现原理详解
# 浅谈Laravel队列实现原理解决问题记录
# Laravel模型事件的实现原理详解
# Laravel框架生命周期与原理分析
# 的是
# 自动加载
# 来完成
# 加载
# 都将
# 列子
# 返回值
# 是在
# 相关内容
# 就能
# 说了
# 不多
# 是从
# 一大
# 用了
# 给大家
# 当我们
# 这篇文章
# 谢谢大家
# 来实现
相关文章:
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
非常酷的网站设计制作软件,酷培ai教育官方网站?
电商网站制作公司有哪些,1688网是什么意思?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
建站主机如何选?高性价比方案全解析
如何快速建站并高效导出源代码?
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
学校为何禁止电信移动建设网站?
如何在IIS7上新建站点并设置安全权限?
如何高效完成自助建站业务培训?
南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?
盐城做公司网站,江苏电子版退休证办理流程?
如何选购建站域名与空间?自助平台全解析
香港服务器如何优化才能显著提升网站加载速度?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
临沂网站制作企业,临沂第三中学官方网站?
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
定制建站方案优化指南:企业官网开发与建站费用解析
网站制作知乎推荐,想做自己的网站用什么工具比较好?
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
建站之星与建站宝盒如何选择最佳方案?
如何通过VPS建站无需域名直接访问?
宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?
建站主机无法访问?如何排查域名与服务器问题
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
建站主机核心功能解析:服务器选择与网站搭建流程指南
个人网站制作流程图片大全,个人网站如何注销?
实例解析angularjs的filter过滤器
网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?
威客平台建站流程解析:高效搭建教程与设计优化方案
建站为何优先选择香港服务器?
宝塔Windows建站如何避免显示默认IIS页面?
Python lxml的etree和ElementTree有什么区别
如何在Windows环境下新建FTP站点并设置权限?
如何在Golang中处理模块冲突_解决依赖版本不兼容问题
如何在橙子建站上传落地页?操作指南详解
php条件判断怎么写_ifelse和switchcase的使用区别【对比】
百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?
如何通过西部数码建站助手快速创建专业网站?
详解jQuery中基本的动画方法
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
如何通过免费商城建站系统源码自定义网站主题与功能?
香港服务器部署网站为何提示未备案?
内部网站制作流程,如何建立公司内部网站?
Bpmn 2.0的XML文件怎么画流程图
如何通过.red域名打造高辨识度品牌网站?
,怎么在广州志愿者网站注册?
免费网站制作appp,免费制作app哪个平台好?
公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?
*请认真填写需求信息,我们会在24小时内与您取得联系。