Laravel的门面Facades是什么
门面为应用服务容器的绑定类提供了一个静态接口。Laravel内置了很多门面,你可能在不知道的情况下正在使用它们。laravel的门面作为服务容器中低层类的静态代理,相比于传统静态方法,在维护时能够提供易于测试、更加灵活、简明优雅的语法。
何时使用门面Facades
门面有许多优点,其提供了简单易记的语法,让我妈无需记住长长的类名即可使用laravel提供的功能特性,此外,由于他们对php动态方法的独到用法,使得他们很容易测试。
但是使用门面也有需要注意的地方,一个最主要的危险就是类范围蠕变。由于门面如此好用并且不需要注入,在单个类中使用过多门面,会让类很容易变得越来越大。使用依赖注入则会让此类问题缓解,因为一个巨大的构造函数会让我们很容易判断类在变大。因此,使用门面的时候尤其注意类的大小,一遍控制其有限职责
门面的工作原理
门面工作原理分为两步,
第一步是编写门面类
class Cache extends Facade { /** * 获取组件注册名称 * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } }
他会通过服务容器绑定的接口名获取对应类的实例
他会调用魔术方法__callStatic,通过这个魔术方法实现调用静态方法去调用实例的动态方法
/** * Handle dynamic, static calls to the object. * * @param string $method * @param array $args * @return mixed * * @throws \RuntimeException */ public static function __callStatic($method, $args) { //通过第一步获取到的服务容器实例 $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } //调用实例的动态方法 return $instance->$method(...$args); }
总的来说:在laravel应用阿忠,门面就是一个为容器中对象提供访问方式的类。该机制原理由Facade类实现。laravel自带的门面,以及我们创建的自定义门面,都会继承自Illuminate\Support\Facades\Facade
基类.
门面类只需要实现一个方法:getFacadeAccessor
。正是这个方法定义了从容器中解析什么,然后Facade基类使用魔术方法__callStatic从你的门面调用解析对象.
实时门面(不需要自己编写相对应的门面类,有laravel自己去动态解析获取对应的类
个人理解:相当于省去了第一个步骤,我们创建门面类告诉laravel应用应该从服务容器解析什么,直接通过命名空间自动的解析对应类的实例
<?php
namespace Tests\Feature;
use App\Podcast;
use Tests\TestCase;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;
class PodcastTest extends TestCase
{
use RefreshDatabase;
/**
* A test example.
*
* @return void
*/
public function test_podcast_can_be_published()
{
$podcast = factory(Podcast::class)->create();
Publisher::shouldReceive('publish')->once()->with($podcast);
$podcast->publish();
}
}
上面例子,我们通过命名空间use Facades\App\Contracts\Publisher;
告诉应用我们要使用实时的门面类,通过字符串处理,将App\Contracts\Publisher通过服务容器解析,然后交由门面.