Facades

Introduction

Facades provide a "static" interface to classes that are available in the application's IoC container. Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the IoC container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.

Occasionally, You may wish to create your own facades for your applications and packages, so let's explore the concept, development and usage of these classes.

Note: Before digging into facades, it is strongly recommended that you become very familiar with the Laravel IoC container.

Explanation

In the context of a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the Facade class. Laravel's facades, and any custom facades you create, will extend the base Facade class.

Your facade class only needs to implement a single method: getFacadeAccessor. It's the getFacadeAccessor method's job to define what to resolve from the container. The Facade base class makes use of the __callStatic() magic-method to defer calls from your facade to the resolved object.

So, when you make a facade call like Cache::get, Laravel resolves the Cache manager class out of the IoC container and calls the get method on the class. In technical terms, Laravel Facades are a convenient syntax for using the Laravel IoC container as a service locator.

Practical Usage

In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method get is being called on the Cache class.

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

However, if we look at that Illuminate\Support\Facades\Cache class, you'll see that there is no static method get:

  1. class Cache extends Facade {
  2. /**
  3. * Get the registered name of the component.
  4. *
  5. * @return string
  6. */
  7. protected static function getFacadeAccessor() { return 'cache'; }
  8. }

The Cache class extends the base Facade class and defines a method getFacadeAccessor(). Remember, this method's job is to return the name of an IoC binding.

When a user references any static method on the Cache facade, Laravel resolves the cache binding from the IoC container and runs the requested method (in this case, get) against that object.

So, our Cache::get call could be re-written like so:

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

Creating Facades

Creating a facade for your own application or package is simple. You only need 3 things:

  • An IoC binding.
  • A facade class.
  • A facade alias configuration.

Let's look at an example. Here, we have a class defined as PaymentGateway\Payment.

  1. namespace PaymentGateway;
  2. class Payment {
  3. public function process()
  4. {
  5. //
  6. }
  7. }

This class might live in your app/models directory, or any other directory that Composer knows how to auto-load.

We need to be able to resolve this class from the IoC container. So, let's add a binding:

  1. App::bind('payment', function()
  2. {
  3. return new \PaymentGateway\Payment;
  4. });

A great place to register this binding would be to create a new service provider named PaymentServiceProvider, and add this binding to the register method. You can then configure Laravel to load your service provider from the app/config/app.php configuration file.

Next, we can create our own facade class:

  1. use Illuminate\Support\Facades\Facade;
  2. class Payment extends Facade {
  3. protected static function getFacadeAccessor() { return 'payment'; }
  4. }

Finally, if we wish, we can add an alias for our facade to the aliases array in the app/config/app.php configuration file. Now, we can call the process method on an instance of the Payment class.

  1. Payment::process();

A Note On Auto-Loading Aliases

Classes in the aliases array are not available in some instances because PHP will not attempt to autoload undefined type-hinted classes. If \ServiceWrapper\ApiTimeoutException is aliased to ApiTimeoutException, a catch(ApiTimeoutException $e) outside of the namespace \ServiceWrapper will never catch the exception, even if one is thrown. A similar problem is found in Models which have type hints to aliased classes. The only workaround is to forego aliasing and use the classes you wish to type hint at the top of each file which requires them.

Mocking Facades

Unit testing is an important aspect of why facades work the way that they do. In fact, testability is the primary reason for facades to even exist. For more information, check out the mocking facades section of the documentation.

Facade Class Reference

Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The IoC binding key is also included where applicable.

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