Facades为应用程序的 服务容器 中可用的类提供了一个 静态接口

  • 最直观的好处

就是需记住必须手动注入或配置的长长的类名。因此有人也理解Facades就是一个“快捷别名”

怎么变得更快捷呢?

# 使用make 去访问注册日志对象的info方法
$container->make('log')->info('message') # 使用arrayaccess的方式
$container["log"]->info('message') # 使用Facade访问Logger对象的info方法, 不需要使用容器去获取一个对象。
Log::info('message');
  • 主要风险

会引起类作用范围的膨胀。因为 Facades 使用起来非常简单而且不需要注入,就会使得我们在不经意间在单个类中使用许多 Facades,从而导致类变的越来越大。

而使用依赖注入的时候,使用的类越多,构造方法就会越长,在视觉上就会引起注意,提醒你这个类有点庞大了。

  • 在laravel中有许多辅助函数的功能都有与之对应的 Facade。

例如,下面这个 Facade 的调用和辅助函数的作用是一样的:

return View::make('profile');

return view('profile');
  • Facades的工作原理

文件位于Illuminate\Support\Facades目录下

我们分析Cache 类

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use App\Http\Controllers\Controller; class UserController extends Controller
{
/**
* 显示给定用户的信息。
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
$user = Cache::get('user:'.$id); return view('profile', ['user' => $user]);
}
}

我们打开Illuminate\Support\Facades\Cache 这个类,你会发现类中根本没有 get 这个静态方法:

<?php

namespace Illuminate\Support\Facades;

/**
* @see \Illuminate\Cache\CacheManager
* @see \Illuminate\Cache\Repository
*/
class Cache extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'cache';
}
}

既然没有那么我们去他的父类看看,父类也没有get方法,但是有个魔术方法__callStatic(),当找到不method的时候自动调用这个方法,顺着这个方法继续探究

Facades.php 的核心代码分析

    /**
* Get the root object behind the facade.
*
* @return mixed
*/
public static function getFacadeRoot()
{
//2. 这里调用了getFacadeAccessor() 也就是Cache.php中的这个方法,返回了字符串‘cache’
return static::resolveFacadeInstance(static::getFacadeAccessor());
} /**
* Get the registered name of the component.
*
* @return string
*
* @throws \RuntimeException
*/
protected static function getFacadeAccessor()
{
throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
} /**
* Resolve the facade root instance from the container.
*
* @param string|object $name
* @return mixed
*/
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) {
return $name;
} if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
} // 3. 调用了当前类的静态属性,其实最终获取的就是$app['cache'],那么这个属性是怎么初始化的呢,原来在laravel启动的时候调用了setFacadeApplication() return static::$resolvedInstance[$name] = static::$app[$name];
} /**
* Get the application instance behind the facade.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public static function getFacadeApplication()
{
return static::$app;
} /**
* Set the application instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public static function setFacadeApplication($app)
{
//
static::$app = $app;
} /**
* Handle dynamic, static calls to the object.
*
* @param string $method
* @param array $args
* @return mixed
*
* @throws \RuntimeException
*/
public static function __callStatic($method, $args)
{
//1. 当找不到method的时候,调用__callStatic()
$instance = static::getFacadeRoot(); //4. 通过分析返回的$instance就是容器中的$app['cache']实例
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
} //5。 调用上面实例的方法
return $instance->$method(...$args);
}

继续分析上面标注4得到的$app['cache'],我们找到Illuminate\Cache\CacheServiceProvider.php

    public function register()
{
$this->app->singleton('cache', function ($app) {
return new CacheManager($app);
}); $this->app->singleton('cache.store', function ($app) {
return $app['cache']->driver();
}); $this->app->singleton('memcached.connector', function () {
return new MemcachedConnector;
});
}

会发现绑定了单例,返回了new CacheManager($app)对象,想进一步探究可以查看这个CacheManager类,再次不再继续探究。

通过以上我们其实已经明白了门面的套路。

laravel5.5门面的更多相关文章

  1. Laravel5 创建自定义门面(Facade)

    门面为应用服务容器中的绑定类提供了一个“静态”接口.Laravel 内置了很多门面,你可能在不知道的情况下正在使用它们.Laravel 的门面作为服务容器中底层类的“静态代理”,相比于传统静态方法,在 ...

  2. laravel5.5源码笔记(三、门面类facade)

    上次说了provider,那么这次来说说facade 首先是启动的源头,从laravel的kernel类中的$bootstrappers 数组,我们可以看到它的一些系统引导方法,其中的Register ...

  3. laravel5.2总结--门面(facades)

    Facades 为应用程序的服务容器中可用的类提供了一个「静态」接口.   Laravel 本身附带许多的 facades,甚至你可能在不知情的状况下已经在使用他们!   xpower的静态接口(门面 ...

  4. laravel5如何创建service provider和facade

    laravel5如何创建service provider和facade laravel5创建一个facade,可以将某个service注册个门面,这样,使用的时候就不需要麻烦地use 了.文章用一个例 ...

  5. Laravel5 快速认证逻辑流程分析

    Laravel5本身自带一套用户认证功能,只需在新项目下,使用命令行php artisan make:auth 和 php artisan migrate就可以使用自带的快速认证功能. 以下为分析登录 ...

  6. 关于laravel5 消息订阅/发布的理解初

    laravel5.4感觉官网文档说滴不够详细...安装predis官网很详细,这里略过.... 生成命令 直接使用 Artisan 命令 make:command,该命令会在 app/Console/ ...

  7. laravel门面和服务提供者使用

      关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...

  8. laravel5.5 dingo/api+jwt-auth

    因为laravel5.5 具有发现包功能,只要包做了兼容laravel5.5就可以不用在config/app.php添加额外代码了. 集成dingo/api github:https://github ...

  9. Laravel开发:Laravel框架门面Facade源码分析

    前言 这篇文章我们开始讲 laravel 框架中的门面 Facade,什么是门面呢?官方文档: Facades(读音:/fəˈsäd/ )为应用程序的服务容器中可用的类提供了一个「静态」接口.Lara ...

随机推荐

  1. php的yii框架开发总结5

    MVC架构之model类: 我的日报系统用到的数据表:tbl_dailyreport表 其中anthor_id是外键,对应tbl_user数据表的主键id,下面是tbl_user表 class Dai ...

  2. day001-日期格式类、装拆箱

    1.Object 1.1 String类型可以不用重写toString()方法 1.2 自定义类一般都去重写toString()方法 调用时机: a)对象名调用toString() b)打印输出时,间 ...

  3. input-file类型accept 属性对性能的影响

    上传图片的时候,有时会加一些限制,如下,进行上传类型的过滤,如 <input type="file" name="pic" id="pic&qu ...

  4. COGS 678. 双重回文数

    ★   输入文件:dualpal.in   输出文件:dualpal.out   简单对比时间限制:1 s   内存限制:128 MB Dual Palindromes 双重回文数 描述 [USACO ...

  5. leetcode: 数组

    1. longest-consecutive-sequence Given an unsorted array of integers, find the length of the longest ...

  6. 【BZOJ5212】[ZJOI2018] 历史(LCT大黑题)

    点此看题面 大致题意: 给定一棵树每个节点\(Access\)的次数,求最大虚实链切换次数,带修改. 什么是\(Access\)? 推荐你先去学一学\(LCT\)吧. 初始化(不带修改的做法) 首先考 ...

  7. 配置SSIS 包部署

    包配置是干嘛滴! 使用包配置可以从开发环境的外部设置运行时属性和变量.         把用户变量转换成Config文件 步骤: 准备工作 把第一个例子中的userinfo.txt复制两份,放到同一个 ...

  8. jQuery实现轮播切换以及将其封装成插件(3)

    在前两篇博文中,我们写了一个普通的轮播切换.但是我们不能每一次需要这个功能就把这些代码有重新敲一次.下面我们就将它封装成一个插件. 至于什么是插件,又为什么要封装插件,不是本文考虑的内容.  我们趁着 ...

  9. 第14章 启动文件详解—零死角玩转STM32-F429系列

    第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ...

  10. linux下jdk的安装配置

    1.下载jdk:地址 选中你选择的版本,下载linux版本对应你系统的32位或64位. 我这里选择的是64位. 2.使用你的ssh直连工具把安装包丢到/usr/local/目录下 3.解压安装jdk ...