Facades(一种设计模式,通常翻译为外观模式)提供了一个"static"(静态)接口去访问注册到IoC 容器中的类 。Laravel 含有很多 facades,你可能不知道其实你在某些地方已经使用过它们了。Laravel的"facades"就像"静态代理方法",为IoC容器中的类服务,相比传统的静态方法,在保持了更强的可测试性和灵活性的同时,它提供更简洁,更富有表现力的语法。
有时候, 你可能想为你的应用程序或包创建自己的 facades, 所以,让我们来讨论一下如何开发和使用这些类。
注意: 在深入 facades 之前,我们强烈建议你多了解一下 Laravel IoC 容器。
在 Laravel 应用程序中, facade 是提供从容器中访问对象的类。Facade 类实现了该机制。Laravel的facades,和其他自定义的facades,都需要继承基类Facade
你的 facade 类只需要实现一个方法: getFacadeAccesor 。 getFacadeAccessor 方法的工作是定义如何从容器中取得对象。 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');
要为自己的应用程序或者包创建一个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 工作的重要体现。事实上,可测试性是 facedes 存在的主要原因。要了解更多信息,查看文档模拟 facades部分。
下面你会找到所有的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
|
| 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(马胜盼)