What are facades
Facades provide a “static” interface to classes that are available in your application’s service container. Laravel ships with many facades that provide access to almost all of its features. Laravel facades serve as “static proxies” to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods. All of Laravel’s facades are defined in theIlluminate\Support\Facades namespace.
Don’t worry about fully understanding how facades work at this point. Just learn how to use them and continue learning Laravel.
How facades work
In 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 theFacade class. Laravel’s facades—and any custom facades you create—will extend the base Illuminate\Support\Facades\Facade class.
The Facade base class makes use of the __callStatic() magic method to defer calls from your facade to an object resolved from the container.
Cache facade. This facade serves as a proxy for accessing the underlying implementation of the Illuminate\Contracts\Cache\Factory interface. Any calls we make using the facade will be passed to the underlying instance of Laravel’s cache service.
If we look at the Illuminate\Support\Facades\Cache class, you’ll see that there is no static method get:
Cache facade extends the base Facade class and defines the getFacadeAccessor() method. This method returns the name of a service container binding. When a user references any static method on the Cache facade, Laravel resolves the cache binding from the service container and runs the requested method (in this case, get) against that object.
When to use, and when not to use, facades
The benefits of facades
Facades have many benefits. They provide a terse, memorable syntax that lets you use Laravel’s features without having to remember long class names that must be injected or configured manually. Because of PHP’s unique usage of dynamic methods, they are also very easy to test.Beware of scope creep
The primary risk of using facades is class “scope creep.” Since facades are easy to use and don’t require injection, it’s easy to let your classes grow and continue to use many facades in a single class. Using dependency injection, this potential is mitigated by the visual feedback a large constructor gives you. So, when using facades, pay special attention to the size of your class so that its scope of responsibility stays narrow.Facades vs. dependency injection
One of the primary benefits of dependency injection is the ability to swap implementations of the injected class. This is useful during testing, since you can inject a mock or stub and assert that various methods were called on the stub. Typically, it would not be possible to mock or stub a truly static class method. However, because facades use dynamic methods to proxy method calls to objects resolved from the service container, you can test facades just as you would test an injected class instance.Cache::get was called with the argument we expected:
Facades vs. helper functions
In addition to facades, Laravel provides a variety of “helper” functions that can perform common tasks like generating views, firing events, dispatching jobs, or sending HTTP responses. Many of these helper functions perform the same function as a corresponding facade.Real-time facades
Using real-time facades, you may treat any class in your application as if it were a facade. To illustrate how this can be used, let’s first examine some code that does not use real-time facades. For example, let’s assume ourPodcast model has a publish method. However, in order to publish the podcast, we need to inject a Publisher instance.
Publisher instance. To generate a real-time facade, prefix the namespace of the imported class with Facades.
Facades prefix.
Testing facades
To test a facade, use theshouldReceive method, which returns a Mockery mock instance. Because facades are actually resolved and managed by the service container, they’re far more testable than typical static classes.
| Method | Description |
|---|---|
shouldReceive('method') | Expect the method to be called |
once() | Expect it to be called exactly once |
times(n) | Expect it to be called n times |
with(args) | Expect it to be called with specific arguments |
andReturn(value) | Return the given value |
andReturnNull() | Return null |
Key facades reference
A mapping of commonly used facades to their underlying classes and service container bindings:| Facade | Class | Binding |
|---|---|---|
App | Illuminate\Foundation\Application | app |
Auth | Illuminate\Auth\AuthManager | auth |
Cache | Illuminate\Cache\CacheManager | cache |
Config | Illuminate\Config\Repository | config |
Cookie | Illuminate\Cookie\CookieJar | cookie |
Crypt | Illuminate\Encryption\Encrypter | encrypter |
DB | Illuminate\Database\DatabaseManager | db |
Event | Illuminate\Events\Dispatcher | events |
File | Illuminate\Filesystem\Filesystem | files |
Gate | Illuminate\Contracts\Auth\Access\Gate | — |
Hash | Illuminate\Contracts\Hashing\Hasher | hash |
Http | Illuminate\Http\Client\Factory | — |
Log | Illuminate\Log\LogManager | log |
Mail | Illuminate\Mail\Mailer | mailer |
Notification | Illuminate\Notifications\ChannelManager | — |
Queue | Illuminate\Queue\QueueManager | queue |
RateLimiter | Illuminate\Cache\RateLimiter | — |
Redirect | Illuminate\Routing\Redirector | redirect |
Request | Illuminate\Http\Request | request |
Route | Illuminate\Routing\Router | router |
Schema | Illuminate\Database\Schema\Builder | — |
Session | Illuminate\Session\SessionManager | session |
Storage | Illuminate\Filesystem\FilesystemManager | filesystem |
URL | Illuminate\Routing\UrlGenerator | url |
Validator | Illuminate\Validation\Factory | validator |
View | Illuminate\View\Factory | view |
Next steps
Contracts
Learn about Contracts and how they complement facades.