跳到主要内容
版本:4.2

Facades

介绍​

Facades 提供一个静态接口让类可以在应用程序的 IoC 容器 里运用。 Laravel 附带许多 facades,甚至您可能已经在使用它们即使您并不知道! Laravel 的 "facades" 在 IoC 容器里面作为的基底类的静态代理,提供有简洁、易表达优点的语法,同时维持比传统的静态方法更高的可测试性和弹性。

您偶尔或许会希望为您的应用程序和扩展包建立自己的 facades,所以让我们来探索这些类的概念、开发和用法。

提示

在深入 facades 之前,强烈建议您先熟悉 Laravel IoC 容器。

解释​

在 Laravel 应用程序的环境中, facade 是个提供从容器获取对象的类。 使这个机制可以运作的原因在 Facade 类中。 Laravel 的 facades 和任何您建立的自定义 facades,将会继承基本的 Facade 类。

您的 facade 类只需要去实现一个方法: getFacadeAccessor。 getFacadeAccessor 方法的工作是定义要从容器解析什么。 基本的 Facade 类利用 __callStatic() 魔术方法去从您的 facade 调用到解析对象。

所以当您对 facade 调用,例如 Cache::get, Laravel 从 IoC 容器解析缓存管理类出来,并对类调用 get 方法。 用术语来说, Laravel Facades 是使用 Laravel IoC 容器作为服务定位器的便捷语法。

实际用法​

在下面的例子,对 Laravel 缓存系统进行调用。 简单看过这代码,有人可能会以为静态方法 get 是被 Cache 类调用。

$value = Cache::get('key');

然而,如果我们去看 Illuminate\Support\Facades\Cache 类, 您将会看到他没有静态方法 get:

class Cache extends Facade {

/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'cache'; }

}

Cache 类继承基本的 Facade 类并定义方法 getFacadeAccessor()。 记住,这个方法的工作是回传 IoC 绑定的名称。

当用户参考 Cache facade 的任何静态方法, Laravel 会从 IoC 容器解析被绑定 cache ,并对该对象执行被请求的方法 (在这个例子, get)。

所以我们的 Cache::get 调用可以被重写成这样:

$value = $app->make('cache')->get('key');

建立 Facades​

为您的应用程序或扩展包建立 facade 是很简单的。 您只需要 3 个东西:

  • 一个 IoC 绑定。
  • 一个 facade 类。
  • 一个 facade 别名设定。

让我们来看个例子。 这里我们有一个定义为 PaymentGateway\Payment 的类。

namespace PaymentGateway;

class Payment {

public function process()
{
//
}

}

这个类可以存在在您的 app/models 文件夹,或者任何其他 Composer 知道如何自动载入的文件夹。

我们需要可以从 IoC 容器解析出这个类。 所以,让我们来加个绑定:

App::bind('payment', function()
{
return new \PaymentGateway\Payment;
});

注册这个绑定的好方式是建立新的 服务提供者 命名为 PaymentServiceProvider,并把这个绑定加到 register 方法。 再来您可以从 app/config/app.php 文件设定让 Laravel 载入您的服务提供者。

接下来,我们可以建立我们自己的 facade 类:

use Illuminate\Support\Facades\Facade;

class Payment extends Facade {

protected static function getFacadeAccessor() { return 'payment'; }

}

最后,如果我们希望,我们可以在 app/config/app.php 配置文件为我们的 facade 加个别名到 aliases 数组。 现在我们可以对 Payment 类的实体调用 process 方法。

Payment::process();

自动载入别名的附注​

在 aliases 数组中的类在某些实体中不能使用,因为 PHP 将不会尝试去自动载入未定义的类型暗示类。 如果 \ServiceWrapper\ApiTimeoutException 命别名为 ApiTimeoutException, 在 \ServiceWrapper 命名空间外面的 catch(ApiTimeoutException $e) 将永远捕捉不到异常,即便有异常被抛出。类似的问题在有类型暗示的别名类模型一样会发生。 唯一的解决办法就是放弃别名并用 use 在每一个文件的最上面引入您希望暗示类型的类。

模拟 Facades​

单元测试是为什么现在 facades 采用这样的工作方式的重要面向。 事实上,可测试性甚至是 facades 存在的主要理由。 想要获得更多信息,请查看文件的 mocking facades 部分。

Facade 类参考​

您将会在下面找到每一个 facade 和它的基底类。 这是个可以从一个给定的 facade 根源快速地深入 API 文件的有用工具。 可应用的 IoC 绑定 关键字也包含在里面。

FacadeClassIoC Binding
AppIlluminate\Foundation\Applicationapp
ArtisanIlluminate\Console\Applicationartisan
AuthIlluminate\Auth\AuthManagerauth
Auth (Instance)Illuminate\Auth\Guard
BladeIlluminate\View\Compilers\BladeCompilerblade.compiler
CacheIlluminate\Cache\Repositorycache
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
DB (Instance)Illuminate\Database\Connection
EventIlluminate\Events\Dispatcherevents
FileIlluminate\Filesystem\Filesystemfiles
FormIlluminate\Html\FormBuilderform
HashIlluminate\Hashing\HasherInterfacehash
HTMLIlluminate\Html\HtmlBuilderhtml
InputIlluminate\Http\Requestrequest
LangIlluminate\Translation\Translatortranslator
LogIlluminate\Log\Writerlog
MailIlluminate\Mail\Mailermailer
PaginatorIlluminate\Pagination\Factorypaginator
Paginator (Instance)Illuminate\Pagination\Paginator
PasswordIlluminate\Auth\Reminders\PasswordBrokerauth.reminder
QueueIlluminate\Queue\QueueManagerqueue
Queue (Instance)Illuminate\Queue\QueueInterface
Queue (Base Class)Illuminate\Queue\Queue
RedirectIlluminate\Routing\Redirectorredirect
RedisIlluminate\Redis\Databaseredis
RequestIlluminate\Http\Requestrequest
ResponseIlluminate\Support\Facades\Response
RouteIlluminate\Routing\Routerrouter
SchemaIlluminate\Database\Schema\Blueprint
SessionIlluminate\Session\SessionManagersession
Session (Instance)Illuminate\Session\Store
SSHIlluminate\Remote\RemoteManagerremote
SSH (Instance)Illuminate\Remote\Connection
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
Validator (Instance)Illuminate\Validation\Validator
ViewIlluminate\View\Factoryview
View (Instance)Illuminate\View\View