Facades

介绍

Facades(一种设计模式,通常翻译为外观模式)提供了一个"static"(静态)接口去访问注册到IoC 容器中的类 。Laravel 含有很多 facades,你可能不知道其实你在某些地方已经使用过它们了。Laravel的"facades"就像"静态代理方法",为IoC容器中的类服务,相比传统的静态方法,在保持了更强的可测试性和灵活性的同时,它提供更简洁,更富有表现力的语法。

有时候, 你可能想为你的应用程序或包创建自己的 facades, 所以,让我们来讨论一下如何开发和使用这些类。

注意: 在深入 facades 之前,我们强烈建议你多了解一下 Laravel IoC 容器

说明

在 Laravel 应用程序中, facade 是提供从容器中访问对象的类。Facade 类实现了该机制。Laravel的facades,和其他自定义的facades,都需要继承基类Facade

你的 facade 类只需要实现一个方法: getFacadeAccesorgetFacadeAccessor 方法的工作是定义如何从容器中取得对象。 Facades 基类构建了 __callStatic() 魔术方法来从 facade 延迟访问取得对象。

因此,当你使用facade调用,类似Cache::get,Laravel会从IoC容器取得Cache管理类并调用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是非常简单的。你只需要做三件事情:

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

namespace PaymentGateway;

class Payment {

    public function process()
    {
        //
    }

}

这个类可以放在app/models目录,或者其他任何Composer能够自动载入的位置。

我们需要能够在 IoC 容器中取得该类。所以,让我们增加一个绑定:

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

最好注册该绑定的位置是创建一个新的名为PaymentServiceProvider服务提供器,并且将该绑定加入到 register 方法。接下来你就可以配置 Laravel app/config/app.php 配置文件来加载该服务提供器。

接下来,我们就可以创建我们的 facade 类:

use Illuminate\Support\Facades\Facade;

class Payment extends Facade {

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

}

最后,如果你想,我们可以为我们 facade 设置一个别名到 app/config/app.php 配置文件里的 aliases 数组。现在,我们能够调用 Payment 类实例的 process 方法。

Payment::process();

关于自动载入别名一些注意点

aliases数组中的有些类接口可能是不可行的,因为PHP不会尝试去自动载入未定义的类型约定。假设\ServiceWrapper\ApiTimeoutException别名是ApiTimeoutException, 如果catch(ApiTimeoutException $e) 是在\ServiceWrapper命名空间之外使用,它将会永远不会被捕获到, 即使真的有一个异常被抛出。 一个类似的问题存在在那些进行类型约定的别名类上。唯一的变通方法是摒弃别名,在每个你想使用类型约定的文件的开始的地方使用use

模拟Facades

单元测试是 facades 工作的重要体现。事实上,可测试性是 facedes 存在的主要原因。要了解更多信息,查看文档模拟 facades部分。

Facade 类参考

下面你会找到所有的facade以及其包含的类。这是一个非常有用的工具,可以根据给定的facade快速定位到API文档。适用于IoC 绑定 的也同时给出了其key。

Facade Class IoC Binding
App Illuminate\Foundation\Application app
Artisan Illuminate\Console\Application artisan
Auth Illuminate\Auth\AuthManager auth
Auth (Instance) Illuminate\Auth\Guard
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Cache Illuminate\Cache\Repository cache
Config Illuminate\Config\Repository config
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
DB Illuminate\Database\DatabaseManager db
DB (Instance) Illuminate\Database\Connection
Event Illuminate\Events\Dispatcher events
File Illuminate\Filesystem\Filesystem files
Form Illuminate\Html\FormBuilder form
Hash Illuminate\Hashing\HasherInterface hash
HTML Illuminate\Html\HtmlBuilder html
Input Illuminate\Http\Request request
Lang Illuminate\Translation\Translator translator
Log Illuminate\Log\Writer log
Mail Illuminate\Mail\Mailer mailer
Paginator Illuminate\Pagination\Factory paginator
Paginator (Instance) Illuminate\Pagination\Paginator
Password Illuminate\Auth\Reminders\PasswordBroker auth.reminder
Queue Illuminate\Queue\QueueManager queue
Queue (Instance) Illuminate\Queue\QueueInterface
Queue (Base Class) Illuminate\Queue\Queue
Redirect Illuminate\Routing\Redirector redirect
Redis Illuminate\Redis\Database redis
Request Illuminate\Http\Request request
Response Illuminate\Support\Facades\Response
Route Illuminate\Routing\Router router
Schema Illuminate\Database\Schema\Blueprint
Session Illuminate\Session\SessionManager session
Session (Instance) Illuminate\Session\Store
SSH Illuminate\Remote\RemoteManager remote
SSH (Instance) Illuminate\Remote\Connection
URL Illuminate\Routing\UrlGenerator url
Validator Illuminate\Validation\Factory validator
Validator (Instance) Illuminate\Validation\Validator
View Illuminate\View\Factory view
View (Instance) Illuminate\View\View

译者:mpandar(马胜盼)