Skip to content
虚位以待
赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

外观模式

介绍

外观提供了一个“静态”接口来访问应用程序的 IoC 容器 中的类。Laravel 附带了许多外观,您可能在不知不觉中已经在使用它们!Laravel 的“外观”作为 IoC 容器中底层类的“静态代理”,提供了简洁、富有表现力的语法,同时比传统的静态方法具有更高的可测试性和灵活性。

有时,您可能希望为您的应用程序和包创建自己的外观,因此让我们来探索这些类的概念、开发和使用。

NOTE

在深入了解外观之前,强烈建议您非常熟悉 Laravel 的 IoC 容器

解释

在 Laravel 应用程序的上下文中,外观是一个提供对容器中对象访问的类。使这项工作成为可能的机制在 Facade 类中。Laravel 的外观以及您创建的任何自定义外观都将扩展基础 Facade 类。

您的外观类只需要实现一个方法:getFacadeAccessorgetFacadeAccessor 方法的任务是定义从容器中解析什么。Facade 基类利用 __callStatic() 魔术方法将来自外观的调用延迟到已解析的对象。

因此,当您进行类似 Cache::get 的外观调用时,Laravel 会从 IoC 容器中解析缓存管理器类,并在该类上调用 get 方法。从技术上讲,Laravel 外观是使用 Laravel IoC 容器作为服务定位器的便捷语法。

实际使用

在下面的示例中,调用了 Laravel 缓存系统。通过查看此代码,您可能会认为正在调用 Cache 类上的静态方法 get

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

然而,如果我们查看 Illuminate\Support\Facades\Cache 类,您会发现没有静态方法 get

php
class Cache extends Facade {

	/**
	 * 获取组件的注册名称。
	 *
	 * @return string
	 */
	protected static function getFacadeAccessor() { return 'cache'; }

}

Cache 类扩展了基础 Facade 类并定义了一个方法 getFacadeAccessor()。请记住,此方法的任务是返回 IoC 绑定的名称。

当用户引用 Cache 外观上的任何静态方法时,Laravel 会从 IoC 容器中解析 cache 绑定,并在该对象上运行请求的方法(在本例中为 get)。

因此,我们的 Cache::get 调用可以重写为:

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

创建外观

为您自己的应用程序或包创建外观很简单。您只需要 3 件事:

  • 一个 IoC 绑定。
  • 一个外观类。
  • 一个外观别名配置。

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

php
namespace PaymentGateway;

class Payment {

	public function process()
	{
		//
	}

}

此类可能位于您的 app/models 目录中,或 Composer 知道如何自动加载的任何其他目录中。

我们需要能够从 IoC 容器中解析此类。因此,让我们添加一个绑定:

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

注册此绑定的一个好地方是创建一个名为 PaymentServiceProvider 的新 服务提供者,并将此绑定添加到 register 方法中。然后,您可以配置 Laravel 从 app/config/app.php 配置文件加载您的服务提供者。

接下来,我们可以创建我们自己的外观类:

php
use Illuminate\Support\Facades\Facade;

class Payment extends Facade {

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

}

最后,如果我们愿意,我们可以在 app/config/app.php 配置文件的 aliases 数组中为我们的外观添加一个别名。现在,我们可以在 Payment 类的实例上调用 process 方法。

php
Payment::process();

关于自动加载别名的注意事项

在某些情况下,aliases 数组中的类不可用,因为 PHP 不会尝试自动加载未定义的类型提示类。如果 \ServiceWrapper\ApiTimeoutException 被别名为 ApiTimeoutException,则在命名空间 \ServiceWrapper 之外的 catch(ApiTimeoutException $e) 永远不会捕获异常,即使抛出了一个异常。在具有类型提示到别名类的模型中也会发现类似的问题。唯一的解决方法是放弃别名,并在每个需要它们的文件顶部 use 您希望类型提示的类。

模拟外观

单元测试是外观工作方式的重要方面。事实上,可测试性是外观存在的主要原因。有关更多信息,请查看文档的 模拟外观 部分。

外观类参考

下面您将找到每个外观及其底层类。这是快速深入了解给定外观根的 API 文档的有用工具。还包括 IoC 绑定 键(如适用)。

外观IoC 绑定
AppIlluminate\Foundation\Applicationapp
ArtisanIlluminate\Console\Applicationartisan
AuthIlluminate\Auth\AuthManagerauth
Auth (实例)Illuminate\Auth\Guard
BladeIlluminate\View\Compilers\BladeCompilerblade.compiler
CacheIlluminate\Cache\Repositorycache
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
DB (实例)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 (实例)Illuminate\Pagination\Paginator
PasswordIlluminate\Auth\Reminders\PasswordBrokerauth.reminder
QueueIlluminate\Queue\QueueManagerqueue
Queue (实例)Illuminate\Queue\QueueInterface
Queue (基类)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 (实例)Illuminate\Session\Store
SSHIlluminate\Remote\RemoteManagerremote
SSH (实例)Illuminate\Remote\Connection
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
Validator (实例)Illuminate\Validation\Validator
ViewIlluminate\View\Factoryview
View (实例)Illuminate\View\View