在代码中获取到容器实例(Laravel)

2022-05-15 0 753

本文由laravel教程栏目给大家介绍怎么在代码中获取到容器实例,希望对需要的朋友有所帮助!

laravel容器实例在整个请求生命周期中都是唯一的,且管理着所有的服务组件实例。那么有哪些方式能够拿到laravel容器的实例呢?常用的有以下几种方式:

1) 通过app这个help函数:

$app = app();

app这个辅助函数定义在

在代码中获取到容器实例(Laravel)

文件里面,这个文件定义了很多help函数,并且会通过composer自动加载到项目中。所以,在参与http请求处理的任何代码位置都能够访问其中的函数,比如app()。

2)通过App这个Facade

<?phpRoute::get('/', function () {    dd(App::basePath());    return '';});

通过App这个Facade拿容器实例的方式,跟上面不同的是,不能把App先赋给一个变量,然后通过变量来调用容器的方法。这是因为App相当于只是一个类名,我们不能把一个类名复制一个变量。$app = App;不是一个合法的可执行的语句,而$app = app();却是一个合法的可执行的语句,因为它后面有app(),表示函数调用。App::basePath();也是一个合法的语句,它就是在调用类的静态方法。

再补充2点:

第一点: Facade是laravel框架里面比较特殊的一个特性,每个Facade都会与容器里面的一个实例对象关联,我们可以直接通过Facade类静态方法调用的形式来调用它关联的实例对象的方法。比如App这个Facade,调用App::basePath()的时候,实际相当于app()->basePath()。

这个底层机制也是依赖于php语言的特性才能实现的,需要在每一个Facade里面,设定一个静态成员并关联到一个服务的实例对象,当调用Facade类的静态方法的时候,解析出调用的方法名,再去调用关联的服务实例的同名方法,最后把结果返回。

我认为理解Facade能起到什么作用就够了,不一定要深究到它底层去了解实现的细节,毕竟在实际的开发中,不用Facade,也完全不影响laravel框架的使用。另外在实际编码中,要自定义一个Facade也非常容易,只要继承laravel封装的Facade基类即可:

<?phpnamespace ThirdProviders\\CasServer\\Facades;use Illuminate\\Support\\Facades\\Facade;use ThirdProviders\\CasServer\\CasServerManager;class CasServer extends Facade{    protected static function getFacadeAccessor()    {        return CasServerManager::class;    }}

实现Facade基类的getFacadeAccessor方法,laravel框架就知道这个Facade类该与哪个服务实例关联起来了。实际上这个getFacadeAccess方法,返回的名称就是后面要介绍的服务绑定名称。在laravel容器里面,一个服务实例,都会有一个固定的绑定名称,通过这个名称就能找到这个实例。所以为啥Facade类只要返回服务绑定名称即可。

我们可以看看App这个Facade类的代码:

<?phpnamespace Illuminate\\Support\\Facades;/** * @see \\Illuminate\\Foundation\\Application */class App extends Facade{    /**     * Get the registered name of the component.     *     * @return string     */    protected static function getFacadeAccessor()    {        return 'app';    }}

它的getFacadeAccessor返回的就是一个字符串“app”,这个app就是laravel容器自己绑定自己时用的名称。

第二点:从上一点最后App这个Facade的源码可以看出,App这个Facade的全类名其实是:Illuminate\\Support\\Facades\\App,那为什么我们在代码里面能够直接通过App这个简短的名称就能访问到呢:

<?phpRoute::get('/', function () {    dd(App::basePath());    return '';});

你看以上代码完全没有用到use或者完全限定的方式来使用Illuminate\\Support\\Facades\\App。实际上App跟Illuminate\\Support\\Facades\\App是完全等价的,只不过App比Illuminate\\Support\\Facades\\App要简短很多,而且不需要use,所以用起来方便,那么它是怎么实现的?这跟laravel容器配置的别名有关系,在config/app.php中,

有一节aliases专门用来配置一些类型的别名:

'aliases' => [    'App' => Illuminate\\Support\\Facades\\App::class,    'Artisan' => Illuminate\\Support\\Facades\\Artisan::class,    'Auth' => Illuminate\\Support\\Facades\\Auth::class,    'Blade' => Illuminate\\Support\\Facades\\Blade::class,    'Bus' => Illuminate\\Support\\Facades\\Bus::class,    'Cache' => Illuminate\\Support\\Facades\\Cache::class,    'Config' => Illuminate\\Support\\Facades\\Config::class,    'Cookie' => Illuminate\\Support\\Facades\\Cookie::class,    'Crypt' => Illuminate\\Support\\Facades\\Crypt::class,    'DB' => Illuminate\\Support\\Facades\\DB::class,    'Eloquent' => Illuminate\\Database\\Eloquent\\Model::class,    'Event' => Illuminate\\Support\\Facades\\Event::class,    'File' => Illuminate\\Support\\Facades\\File::class,    'Gate' => Illuminate\\Support\\Facades\\Gate::class,    'Hash' => Illuminate\\Support\\Facades\\Hash::class,    'Lang' => Illuminate\\Support\\Facades\\Lang::class,    'Log' => Illuminate\\Support\\Facades\\Log::class,    'Mail' => Illuminate\\Support\\Facades\\Mail::class,    'Notification' => Illuminate\\Support\\Facades\\Notification::class,    'Password' => Illuminate\\Support\\Facades\\Password::class,    'Queue' => Illuminate\\Support\\Facades\\Queue::class,    'Redirect' => Illuminate\\Support\\Facades\\Redirect::class,    'Redis' => Illuminate\\Support\\Facades\\Redis::class,    'Request' => Illuminate\\Support\\Facades\\Request::class,    'Response' => Illuminate\\Support\\Facades\\Response::class,    'Route' => Illuminate\\Support\\Facades\\Route::class,    'Schema' => Illuminate\\Support\\Facades\\Schema::class,    'Session' => Illuminate\\Support\\Facades\\Session::class,    'Storage' => Illuminate\\Support\\Facades\\Storage::class,    'URL' => Illuminate\\Support\\Facades\\URL::class,    'Validator' => Illuminate\\Support\\Facades\\Validator::class,    'View' => Illuminate\\Support\\Facades\\View::class],

然后在laravel框架处理请求过程中,会通过Illuminate\\Foundation\\Bootstrap\\RegisterFacades这个类来注册这些别名到全局环境里面:

<?phpnamespace Illuminate\\Foundation\\Bootstrap;use Illuminate\\Support\\Facades\\Facade;use Illuminate\\Foundation\\AliasLoader;use Illuminate\\Contracts\\Foundation\\Application;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($app->make('config')->get('app.aliases', []))->register();    }}

所以我们才能直接通过别名,代替完整的类型名做同样的访问功能。如果你自己写了一些类,名称很长,并且在代码里面用的特别多,也可以考虑配置到config/app.php别名里面去,laravel会帮我们注册。

3)另外一种方式拿到laravel容器实例就是在服务提供者里面直接使用$this->app

服务提供者后面还会介绍,现在只是引入。因为服务提供者类都是由laravel容器实例化的,这些类都继承自Illuminate\\Support\\ServiceProvider,它定义了一个实例属性$app

在代码中获取到容器实例(Laravel)

laravel在实例化服务提供者的时候,会把laravel容器实例注入到这个$app上面。所以我们在服务提供者里面,始终能通过$this->$app访问到laravel容器实例,而不需要再使用app()函数或者App Facade了。

更多laravel技术文章,请访问laravel教程栏目!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

【声明:根据2013年1月30日《计算机软件保护条例》2次修订第17条规定: 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存 储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬! 鉴于此,也希望大家按此说明研究软件!】
本站所有源码尽量保证原汁原味,如有特殊情况会作出声明及标注,网站资源不做任何二次加密(原版加密除外,不影响程序使用的不会做解密处理),方便您更好的学习参考。 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

即刻码站__国内靠谱的站长资源下载平台 php教程 在代码中获取到容器实例(Laravel) https://www.jike1995.com/35870.html

常见问题
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务