laravel5.5门面
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门面的更多相关文章
- Laravel5 创建自定义门面(Facade)
		门面为应用服务容器中的绑定类提供了一个“静态”接口.Laravel 内置了很多门面,你可能在不知道的情况下正在使用它们.Laravel 的门面作为服务容器中底层类的“静态代理”,相比于传统静态方法,在 ... 
- laravel5.5源码笔记(三、门面类facade)
		上次说了provider,那么这次来说说facade 首先是启动的源头,从laravel的kernel类中的$bootstrappers 数组,我们可以看到它的一些系统引导方法,其中的Register ... 
- laravel5.2总结--门面(facades)
		Facades 为应用程序的服务容器中可用的类提供了一个「静态」接口. Laravel 本身附带许多的 facades,甚至你可能在不知情的状况下已经在使用他们! xpower的静态接口(门面 ... 
- laravel5如何创建service provider和facade
		laravel5如何创建service provider和facade laravel5创建一个facade,可以将某个service注册个门面,这样,使用的时候就不需要麻烦地use 了.文章用一个例 ... 
- Laravel5 快速认证逻辑流程分析
		Laravel5本身自带一套用户认证功能,只需在新项目下,使用命令行php artisan make:auth 和 php artisan migrate就可以使用自带的快速认证功能. 以下为分析登录 ... 
- 关于laravel5  消息订阅/发布的理解初
		laravel5.4感觉官网文档说滴不够详细...安装predis官网很详细,这里略过.... 生成命令 直接使用 Artisan 命令 make:command,该命令会在 app/Console/ ... 
- laravel门面和服务提供者使用
		关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ... 
- laravel5.5 dingo/api+jwt-auth
		因为laravel5.5 具有发现包功能,只要包做了兼容laravel5.5就可以不用在config/app.php添加额外代码了. 集成dingo/api github:https://github ... 
- Laravel开发:Laravel框架门面Facade源码分析
		前言 这篇文章我们开始讲 laravel 框架中的门面 Facade,什么是门面呢?官方文档: Facades(读音:/fəˈsäd/ )为应用程序的服务容器中可用的类提供了一个「静态」接口.Lara ... 
随机推荐
- linux下搭建svn并同步更新至web目录
			安装svn 使用yum安装 yum install subversion -y 安装成功后查看版本库 svnserve --version 生成目录 cd /var mkdir svn cd svn ... 
- 洛谷 P1080 国王游戏
			题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最 ... 
- PDO数据库类——对query()和exec()的异常监听
			PDO异常类中,query()和exec()方法中执行失败时,默认情况下,我们是无法知道,具体执行失败的原因. 那如果我们想要监听异常的话,肿么整呢? 只要使用setAttribute()方法,即可监 ... 
- python从字符串中提取数字,使用正则表达式
			使用正则表达式 import re D = re.findall(r"\d+\.?\d*",line) print(D) -7.23246 10.8959 5.19534 0.06 ... 
- 在TextBox控件中禁用鼠标右键
			实现效果: 知识运用: MouseEventArgs类的Button属性 TextBox控件的ContextMenu属性 实现代码: private void textBox1_MouseDo ... 
- Python,针对指定文件类型,过滤空行和注释,统计行数
			参考网络上代码编辑而成,无技术含量,可自行定制: 目前亲测有效,若有待完善之处,还望指出! 强调:将此统计py脚本放置项目的根目录下执行即可. 1.遍历文件,递归遍历文件夹中的所有 def getFi ... 
- iOS 实时监测网络状态(通过Reachability)
			在AppDelegate.m中 @property (nonatomic, strong) Reachability *reach; - (BOOL)application:(UIApplicatio ... 
- 读取hdfs目录,并在web页面上展示文件里的内容
			最终效果图 目录树实体类: /** * @Author: DaleyZou * @Description: hdfs 目录结构的实体类,用于展示目录树的支撑操作 * @Date: Created in ... 
- Q&A - 如何获取ip地址所在地
			获取其IP地址后,传入以下URL,并请求该URL,该请求会响应一个JSON格式的数据包,该IP地址的所在地均在这个数据包内 http://int.dpool.sina.com.cn/iplooku ... 
- python实现简单关联规则Apriori算法
			from itertools import combinations from copy import deepcopy # 导入数据,并剔除支持度计数小于min_support的1项集 def lo ... 
