November 21, 2016 —John Koster
This article is part of a four part series all about Laravel facades. Each of the parts are listed below:
It may become necessary when developing certain applications, or when creating packages to write a facade class. Creating a facade class is fairly simple. The first thing that is required is some actual concrete class the facade will be accessing. For this example, the following class will be used:
1<?php 2 3class Calculator { 4 5 /** 6 * Adds two numbers. 7 8 * @param mixed $firstNumber 9 * @param mixed $secondNumber10 * @return mixed11 */12 public function add($firstNumber, $secondNumber)13 {14 return $firstNumber + $secondNumber;15 }16 17 // Possibly many more methods.18 19}
The next thing that needs to happen is the class needs to be registered with the service container:
1<?php2 3App::singleton('math', function()4{5 return new Calculator;6});
Components are typically registered with the service container through the use of Service Providers.
The Calculator
class instance was bound as a singleton because there does not need to possibly hundreds of instances of Calculator
created: many consumers of the class can share a single instance (note that not all classes should be bound as a singleton). The important part is that we have an service container binding: math
which will resolve to an instance of Calculator
.
It is at this point a facade can be created. A facade is created by creating a new class and extending Laravel's abstract Facade
class:
1<?php 2 3use Illuminate\Support\Facades\Facade; 4 5class Math extends Facade { 6 7 /** 8 * Get the registered name of the component. 9 *10 * @return string11 */12 protected static function getFacadeAccessor() { return 'math'; }13 14}
It is important to note that the value returned by the getFacadeAccessor()
function matches the name of the service container binding: math
. The facade will use that value to request a class instance from the service container and redirect method calls to that instance.
We will now examine how we would have used the Calculator
class without the facade:
1<?php namespace App\Http\Controllers; 2 3use Calculator; 4 5class TestController extends Controller { 6 7 public function getIndex() 8 { 9 // We will create an instance, instead of having it supplied10 // through the constructor.11 $calculator = new Calculator;12 13 $result = $calculator->add(1, 2);14 }15 16}
now using the facade:
1<?php namespace App\Http\Controllers; 2 3use Math; 4 5class TestController extends Controller { 6 7 public function getindex() 8 { 9 $result = Math::add(1, 2);10 }11 12}
Creating a facade alias is completely optional. Package developers often include the following steps in their package installation instructions, but it is not required for a facade to work.
In the config/app.php
file, there is an aliases
configuration entry. By default it will look like this:
1<?php 2 3// Other configuration items. 4 5'aliases' => [ 6 7 'App' => 'Illuminate\Support\Facades\App', 8 'Artisan' => 'Illuminate\Support\Facades\Artisan', 9 'Auth' => 'Illuminate\Support\Facades\Auth',10 'Blade' => 'Illuminate\Support\Facades\Blade',11 'Bus' => 'Illuminate\Support\Facades\Bus',12 'Cache' => 'Illuminate\Support\Facades\Cache',13 'Config' => 'Illuminate\Support\Facades\Config',14 'Cookie' => 'Illuminate\Support\Facades\Cookie',15 'Crypt' => 'Illuminate\Support\Facades\Crypt',16 'DB' => 'Illuminate\Support\Facades\DB',17 'Event' => 'Illuminate\Support\Facades\Event',18 'File' => 'Illuminate\Support\Facades\File',19 'Gate' => 'Illuminate\Support\Facades\Gate',20 'Hash' => 'Illuminate\Support\Facades\Hash',21 'Input' => 'Illuminate\Support\Facades\Input',22 'Lang' => 'Illuminate\Support\Facades\Lang',23 'Log' => 'Illuminate\Support\Facades\Log',24 'Mail' => 'Illuminate\Support\Facades\Mail',25 'Password' => 'Illuminate\Support\Facades\Password',26 'Queue' => 'Illuminate\Support\Facades\Queue',27 'Redirect' => 'Illuminate\Support\Facades\Redirect',28 'Redis' => 'Illuminate\Support\Facades\Redis',29 'Request' => 'Illuminate\Support\Facades\Request',30 'Response' => 'Illuminate\Support\Facades\Response',31 'Route' => 'Illuminate\Support\Facades\Route',32 'Schema' => 'Illuminate\Support\Facades\Schema',33 'Session' => 'Illuminate\Support\Facades\Session',34 'Storage' => 'Illuminate\Support\Facades\Storage',35 'URL' => 'Illuminate\Support\Facades\URL',36 'Validator' => 'Illuminate\Support\Facades\Validator',37 'View' => 'Illuminate\Support\Facades\View',38],39 40// Other configuration items.
Examining the above code sample, it can be deduced that to add a new facade alias we simply need to add a new entry to the aliases
array. The key of the entry will become the name of the alias and the value of the entry will become the class being aliased. To make this clearer, in the above list Response
is aliasing Illuminate\Support\Facades\Response
, and both classes can be used interchangeably.
We will use our Math
facade from earlier, and we will assume it was defined in the Our\Applications
\Namespace
. We could create an alias like so:
1<?php2 3 // Previous alias entries.4 5 'Math' => 'Our\Applications\Namespace\Math',
Classes, other than facades, can be added to the aliases
configuration entry. This will cause them to be available under whatever name was provided, and in the global namespace. Although this can be convenient and useful thing to do, other options should be examined first.
∎
The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.