Laravel 门面类:Facade简记

原创 2017年07月06日 14:43:46

这是另一位大哥写的,感觉写的很好,在此感谢他的分享。这位大哥的这篇文章详细介绍了原理,但是感觉初次看的人可能需要下面这个前期知识储备:

还有一点就是我的实际代码和他的有点不同,这里再贴一下实际的源码,顺道也再整理一下思路:

这里拿vendor/laravel/framework/src/Illuminate/Support/Facades/App.php为例进行介绍:

<?php
namespace Illuminate\Support\Facades;

/**
 * 这里顺道记录一个小技巧,在函数前写这样的注释,会被PHPSrorm解析,表示该类所拥有的方法
 * @method static string version()
 * @method static string basePath()
 * @method static string environment()
 * @method static bool isDownForMaintenance()
 * @method static void registerConfiguredProviders()
 * @method static \Illuminate\Support\ServiceProvider register(\Illuminate\Support\ServiceProvider|string $provider, array $options = [], bool $force = false)
 * @method static void registerDeferredProvider(string $provider, string $service = null)
 * @method static void boot()
 * @method static void booting(mixed $callback)
 * @method static void booted(mixed $callback)
 * @method static string getCachedServicesPath()
 *
 * @see \Illuminate\Foundation\Application
 */
class App extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'app';
    }
}

当我们外部这样调用时:

use App;

/App:make('app');

时,根据服务容器的自动依赖注入,(Facade类是App类的抽象类):

<?php

namespace Illuminate\Support\Facades;

use Mockery;
use RuntimeException;
use Mockery\MockInterface;

abstract class Facade{
    //先省略其中的代码
}

会自动调用到App类,接着就是解释如何像调用静态方法一样调用App类中的方法了,根据那位大哥的解释,当我们调用getFacadeAccessor()方法时,在Facades中并没有该静态方法,那么就会调用PHP的魔术方法:__callStatic($method,$args),下面来看其源码:

public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeRoot();
        //先到这里,下面讲解 static::getFacadeRoot() 这个函数
        if (! $instance) {
            throw new RuntimeException('A facade root has not been set.');
        }

        return $instance->$method(...$args);
    }

其中的getFacadeRoot方法如下:

public static function getFacadeRoot()
    {
        //注意,最开始时我们的 getFacadeAccessor() 的返回值是 "app"
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }

接下来再看resolveFacadeInstance

protected static function resolveFacadeInstance($name)
    {
        //如果传入的参数是对象的话,则返回该对象
        if (is_object($name)) {
            return $name;
        }
        //如果该类是在项目加载完成后就自动装载的,则返回该类
        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }
        //如果没有,就到服务容器中去找
        return static::$resolvedInstance[$name] = static::$app[$name];
    }

其实简单点来说就是返回该$name的实例,接着回到最开始的__callStatic函数的剩余部分:

//如果经过上面的`resolveFacadeInstance`函数没有办法获取该类实例的话,那么接下来肯定无法正常运行了,所以这里抛出异常
if (! $instance) {
   throw new RuntimeException('A facade root has not been set.');
}
  //就是在这里调用了该类下面的方法,...$args表示该方法可能存在输入参数,可能不存在
   return $instance->$method(...$args);
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YQXLLWY/article/details/74544199

Laravel Facade 实现原理揭秘

在使用Laravel 框架的时候会看到很多 Cache::get() 这样的用法,称之为 Facade,门面。 但是代码中即没有看到使用 Cache 相关的命名空间,且在 Composer 自动加载中...
  • hizzana
  • hizzana
  • 2016-11-18 09:01:26
  • 3188

对laravel5概念的理解 -- 门面模式(Facade)

前言: 第一次写技术类博客,因为比较懒,至于作为一个懒人为何会写博客,因为记性比较差,常常当初灵光一闪理解的概念最后会忘记。所以还是用文字记录下来,以备自己后查,有缘人看到也可以做个参考,不同意见...
  • cuishuli
  • cuishuli
  • 2016-07-07 17:26:44
  • 2008

4. Laravel5学习笔记:Facade的运行机制

什么是Facades,官方文档如是说: Facades 提供一个 静态接口 给在应用程序的 服务容器 中可以取用的类。Laravel 附带许多 facades,甚至你可能已经在不知情的状况下使用过它们...
  • hel12he
  • hel12he
  • 2015-06-24 12:28:38
  • 2653

Laravel框架学习(一) 如何添加Facade

使用Laravel框架必不可少的会用到它很多强大的Facades,Facades 提供了一个“静态”接口到IoC容器类,也就是说facade 提供了IOC里面的对象(实例) 根据官方提供的步骤  ...
  • wanglitaow
  • wanglitaow
  • 2015-01-14 20:14:42
  • 796

解读Laravel,看PHP如何实现Facade?

刚刚开始学Laravel就会接触到路由 1 2 3 Route::get('/', function () {     retur...
  • duzanuolu
  • duzanuolu
  • 2017-03-20 18:47:03
  • 337

Laravel Composer Package 开发简明教程

在Laravel的文档中有Package Development,对于入门开发人员来说还是比较抽象,因为开发一个包需要了解 Service Providers,Service Providers 和...
  • xionggang1024
  • xionggang1024
  • 2017-08-01 22:11:25
  • 812

Laravel 架构中的 Container/ServiceProvider/Facade

来源:https://phphub.org/topics/769 最近有空继续学习laravel,对laravel文档中系统架构部分基本的有一些了解,和大家分享一下。 containe...
  • kendyhj9999
  • kendyhj9999
  • 2015-05-31 20:19:06
  • 590

Laravel数据库操作之-DB facade

数据库操作之-DB facade 新建数据表与连接数据库 使用DB facade实现CURD 创建数据表DROP TABLE IF EXISTS `student`; CREATE TABLE `st...
  • ks3ks
  • ks3ks
  • 2017-02-09 07:08:32
  • 148
收藏助手
不良信息举报
您举报文章:Laravel 门面类:Facade简记
举报原因:
原因补充:

(最多只允许输入30个字)