Laravel - Facades
Laravel - Facades
Section titled “Laravel - Facades”Introduction
Section titled “Introduction”Facades provide a “static” interface to classes that are available in the application’s service container. 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 the Illuminate\Support\Facades namespace. So, we can easily access a facade like so:
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () { return Cache::get('key');});Throughout the Laravel documentation, many of the examples will use facades to demonstrate various features of the framework.
When to Use Facades
Section titled “When to Use Facades”Facades have many benefits. They provide a terse, memorable syntax that allows you to use Laravel’s features without remembering long class names that must be injected or configured manually. Furthermore, because of their unique usage of PHP’s dynamic methods, they are easy to test.
However, some care must be taken when using facades. The primary danger of facades is class scope creep. Since facades are so easy to use and do not require injection, it can be easy to let your classes grow too large and use many facades in a single class. When using dependency injection, this potential is mitigated by the visual feedback a large constructor gives you that your class is growing too large. So, when using facades, pay special attention to the size of your class so that its scope of responsibility stays narrow.
When building a third-party package that interacts with Laravel, it’s often better to inject Laravel contracts instead of using facades. Since packages are built outside of Laravel itself, you will not have access to Laravel’s facade testing helpers.
How Facades Work
Section titled “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 the Facade 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. 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:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Cache;
class UserController extends Controller{ public function index() { $value = Cache::get('key'); // ... }}Notice that near the top of the file we are “importing” the Cache facade. This facade serves as a proxy to 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 you look at the Illuminate\Support\Facades\Cache class, you’ll find that there is no static method get:
class Cache extends Facade{ protected static function getFacadeAccessor() { return 'cache'; }}Instead, the Cache facade extends the base Facade class and defines the method getFacadeAccessor(). This method’s job is to return 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.
Creating Custom Facades
Section titled “Creating Custom Facades”Creating a facade for your own application or package is simple. You only need three things:
- A service container binding.
- A facade class.
- A facade alias configuration (optional, but common).
Example: Creating a Custom Payment Gateway Facade
Section titled “Example: Creating a Custom Payment Gateway Facade”Step 1: Create the Service Class. This is the class that will do the actual work.
Create a file app/Services/PaymentGateway.php:
app/Services/PaymentGateway.php
<?php
namespace App\Services;
class PaymentGateway{ public function processPayment(float $amount) { // In a real application, this would interact with a payment API return "Processing payment of $" . number_format($amount, 2); }}Step 2: Create a Service Provider to bind your class to the service container.
Run php artisan make:provider PaymentServiceProvider in your terminal. This command will create a new provider in app/Providers/PaymentServiceProvider.php. Edit this file:
app/Providers/PaymentServiceProvider.php
<?php
namespace App\Providers;
use App\Services\PaymentGateway;use Illuminate\Support\ServiceProvider;
class PaymentServiceProvider extends ServiceProvider{ public function register(): void { $this->app->bind('payment.gateway', function ($app) { return new PaymentGateway(); }); }
public function boot(): void { // }}Step 3: Register the Service Provider. Add your PaymentServiceProvider to the providers array in your config/app.php configuration file:
config/app.php (snippet from providers array)
'providers' => ServiceProvider::defaultProviders()->merge([ /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\PaymentServiceProvider::class, // Add this line])->toArray(),Step 4: Create the Facade Class. This class should extend Illuminate\Support\Facades\Facade and implement the getFacadeAccessor method. This method should return the service container binding key you used in the service provider (payment.gateway).
Create a file app/Facades/Payment.php:
app/Facades/Payment.php
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Payment extends Facade{ protected static function getFacadeAccessor(): string { return 'payment.gateway'; }}Step 5: (Optional) Add a Facade Alias. If you want to use your facade without importing it by its full namespace, add an alias to the aliases array in your config/app.php configuration file.
config/app.php (snippet from aliases array)
'aliases' => Facade::defaultAliases()->merge([ 'Payment' => App\Facades\Payment::class,])->toArray(),Step 6: Use your new Facade. You can now use your facade in your application, for example, in a route or controller.
routes/web.php
use App\Facades\Payment; // Or use the alias 'Payment' if configured
Route::get('/pay', function(){ return Payment::processPayment(19.99);});Step 7: Test it. Visit http://localhost:8000/pay in your browser. You should see the output: ‘Processing payment of $19.99’.
Facade Class Reference
Section titled “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 service container binding key is also included where applicable.
| Facade | Class | Service Container Binding |
|---|---|---|
| Facade | Class | Service Container Binding |
| App | Illuminate\Foundation\Application | app |
| Artisan | Illuminate\Contracts\Console\Kernel | artisan |
| Auth | Illuminate\Auth\AuthManager | auth |
| Auth (Instance) | Illuminate\Contracts\Auth\Guard | |
| Blade | Illuminate\View\Compilers\BladeCompiler | blade.compiler |
| Broadcast | Illuminate\Contracts\Broadcasting\Factory | broadcast |
| Bus | Illuminate\Contracts\Bus\Dispatcher | bus |
| Cache | Illuminate\Cache\CacheManager | cache |
| Cache (Instance) | Illuminate\Contracts\Cache\Repository | |
| 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 |
| Gate | Illuminate\Contracts\Auth\Access\Gate | gate |
| Hash | Illuminate\Contracts\Hashing\Hasher | hash |
| Http | Illuminate\Support\Facades\Http | http |
| Lang | Illuminate\Translation\Translator | translator |
| Log | Illuminate\Log\LogManager | log |
| Illuminate\Mail\Mailer | mailer | |
| Notification | Illuminate\Notifications\ChannelManager | notification |
| Password | Illuminate\Auth\Passwords\PasswordBrokerManager | auth.password |
| Password (Instance) | Illuminate\Auth\Passwords\PasswordBroker | |
| Queue | Illuminate\Queue\QueueManager | queue |
| Queue (Instance) | Illuminate\Contracts\Queue\Queue | |
| RateLimiter | Illuminate\Cache\RateLimiter | limiter |
| Redirect | Illuminate\Routing\Redirector | redirect |
| Redis | Illuminate\Redis\RedisManager | redis |
| Redis (Instance) | Illuminate\Contracts\Redis\Connection | |
| Request | Illuminate\Http\Request | request |
| Response | Illuminate\Contracts\Routing\ResponseFactory | response |
| Route | Illuminate\Routing\Router | router |
| Schema | Illuminate\Database\Schema\Builder | db.schema |
| Session | Illuminate\Session\SessionManager | session |
| Session (Instance) | Illuminate\Session\Store | |
| Storage | Illuminate\Filesystem\FilesystemManager | filesystem |
| Storage (Instance) | Illuminate\Contracts\Filesystem\Filesystem | |
| URL | Illuminate\Routing\UrlGenerator | url |
| Validator | Illuminate\Validation\Factory | validator |
| Validator (Instance) | Illuminate\Contracts\Validation\Validator | |
| View | Illuminate\View\Factory | view |
| View (Instance) | Illuminate\Contracts\View\View | |
| Vite | Illuminate\Foundation\Vite |
Note: The list above is representative and might not be exhaustive or perfectly up-to-date with the very latest Laravel version, but it covers the most commonly used facades. Always refer to the official Laravel API documentation for the most current information.