首页 > 编程 > PHP > 正文

Laravel核心解读Facades

2020-03-22 19:02:52
字体:
来源:转载
供稿:网友
这篇文章主要介绍了关于Laravel核心解读Facades,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

什么是Facades

Facades是我们在Laravel应用开发中使用频率很高的一个组件,叫组件不太合适,其实它们是一组静态类接口或者说代理,让开发者能简单的访问绑定到服务容器里的各种服务。Laravel文档中对Facades的解释如下:

Facades 为html' target='_blank'>应用程序的 服务容器 中可用的类提供了一个「静态」接口。Laravel 本身附带许多的 facades,甚至你可能在不知情的状况下已经在使用他们!Laravel 「facades」作为在服务容器内基类的「静态代理」,拥有简洁、易表达的语法优点,同时维持着比传统静态方法更高的可测试性和灵活性。

我们经常用的Route就是一个Facade, 它是/Illuminate/Support/Facades/Route类的别名,这个Facade类代理的是注册到服务容器里的router服务,所以通过Route类我们就能够方便地使用router服务中提供的各种服务,而其中涉及到的服务解析完全是隐式地由Laravel完成的,这在一定程度上让应用程序代码变的简洁了不少。下面我们会大概看一下Facades从被注册进Laravel框架到被应用程序使用这中间的流程。Facades是和ServiceProvider紧密配合的所以如果你了解了中间的这些流程对开发自定义Laravel组件会很有帮助。

注册Facades

说到Facades注册又要回到再介绍其它核心组建时提到过很多次的Bootstrap阶段了,在让请求通过中间件和路由之前有一个启动应用程序的过程:

//Class: /Illuminate/Foundation/Http/Kernelprotected function sendRequestThroughRouter($request) $this- app- instance( request , $request); Facade::clearResolvedInstance( request  $this- bootstrap(); return (new Pipeline($this- app)) - send($request) - through($this- app- shouldSkipMiddleware() ? [] : $this- middleware) - then($this- dispatchToRouter());//引导启动Laravel应用程序public function bootstrap() if (! $this- app- hasBeenBootstrapped()) { /**依次执行$bootstrappers中每一个bootstrapper的bootstrap()函数 $bootstrappers = [ Illuminate/Foundation/Bootstrap/DetectEnvironment , Illuminate/Foundation/Bootstrap/LoadConfiguration , Illuminate/Foundation/Bootstrap/ConfigureLogging , Illuminate/Foundation/Bootstrap/HandleExceptions , Illuminate/Foundation/Bootstrap/RegisterFacades , Illuminate/Foundation/Bootstrap/RegisterProviders , Illuminate/Foundation/Bootstrap/BootProviders , ];*/ $this- app- bootstrapWith($this- bootstrappers());}

在启动应用的过程中Illuminate/Foundation/Bootstrap/RegisterFacades这个阶段会注册应用程序里用到的Facades。

class RegisterFacades * Bootstrap the given application. * @param /Illuminate/Contracts/Foundation/Application $app * @return void 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();}

在这里会通过AliasLoader类的实例将为所有Facades注册别名,Facades和别名的对应关系存放在config/app.php文件的$aliases数组中

 aliases = [ App = Illuminate/Support/Facades/App::class, Artisan = Illuminate/Support/Facades/Artisan::class, Auth = Illuminate/Support/Facades/Auth::class, ...... Route = Illuminate/Support/Facades/Route::class, ......]

看一下AliasLoader里是如何注册这些别名的

// class: Illuminate/Foundation/AliasLoaderpublic static function getInstance(array $aliases = []) if (is_null(static::$instance)) { return static::$instance = new static($aliases); $aliases = array_merge(static::$instance- getAliases(), $aliases); static::$instance- setAliases($aliases); return static::$instance;public function register() if (! $this- registered) { $this- prependToLoaderStack(); $this- registered = true;protected function prependToLoaderStack() // 把AliasLoader::load()放入自动加载函数队列中,并置于队列头部 spl_autoload_register([$this, load ], true, true);}

通过上面的代码段可以看到AliasLoader将load方法注册到了SPL __autoload函数队列的头部。看一下load方法的源码:

public function load($alias) if (isset($this- aliases[$alias])) { return class_alias($this- aliases[$alias], $alias);}

在load方法里$aliases配置里的Facade类创建了对应的别名,比如当我们使用别名类Route时PHP会通过AliasLoader的load方法为把Illuminate/Support/Facades/Route::class类创建一个别名类Route,所以我们在程序里使用别Route其实使用的就是`Illuminate/Support/Facades/Route类。

解析Facade代理的服务

把Facades注册到框架后我们在应用程序里就能使用其中的Facade了,比如注册路由时我们经常用Route::get( /uri , Controller@action);,那么Route是怎么代理到路由服务的呢,这就涉及到在Facade里服务的隐式解析了, 我们看一下Route类的源码:

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表