Today we are going to learn about Laravel Facades.
"Laravel has these things called facades - which we can understand as static wrappers around instances (objects) or the non-static interface traditionally used to cull on a given classes behavior."
Out of the gate Laravel comes with several pre-defined Facades - App, Artisan, Blade, Broadcast, View, etc...
Most of these Facades come hooked up with a related global helper function.
Examples of facades that have global helpers:
- The App Facade has a related
app()
global helper function. - The View Facade has a related
view()
global helper function. - The Config Facade has a related
config()
global helper function.
How do we call a Facade?
- 1. Open ther terminal
- 2. Run
php artisan tinker
- 3. Add a Backslash
\
then the given class with a facade.
tinker> \DB::get('users')->all();
How do we create our own custom Facades in Laravel?
- 1. Create a traditional service class (A class that provides a service to our application)
namespace App\Services\Information;
class Info
{
public function example()
{
echo "Example Information";
}
}
Currently to access our Info
class's example() method we would need to do the following.
$instance = new \App\Services\Information;
$instance->example();
// outputs "Example Information"
What we want to be able to do is to access the same class with same function statically and without needing to import the entire class path.
Example: We want to simply be able to do this
\Info::example();
// outputs "Example Information" as well
- 1. We've created our service class
- 2. We need to create our Facade class
- That extends
Illuminate\Support\Facades\Facade
- Implements a
protected static
function calledgetFacadeAccessor()
that returns the key in our service container that we're going to use to bind ourInfo
Service class to the Service Container.
- That extends
namespace App\Services\Information;
use Illuminate\Support\Facades\Facade;
class InfoFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'Info';
}
}
- 3. Now, we need to bind our
Info
Service class to the Service Container with a key ofInfo
sinceInfo
is what is returned by thegetFacadeAccessor
method in theInfoFacade
<?php
namespace App\Providers;
use App\Services\Information\Info;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind('Info', function ($app) {
return new Info();
});
}
}
Now we can resolve an instance of our Info
class by referencing our service container. When we retrieve something from our service container using the 'Info' key, we'll return a new Info Class
object.
Our InfoFacade
references the key that is used to bind the Info Class
to our service container - thus it knows how to resolve the instance from our container.
Now, we have the functionality set up for our Facade. With the Service class binded to the container, and the Facade class referencing the binding that returns an instance of that service class from our container, we can actually use our Facade by referencing the entire class path to our given facade.
\App\Services\Information\InfoFacade::example();
// outputs "Example Information"
We're close, so how do we go from needing to reference the entire class path to our facade like so \App\Services\Information\InfoFacade::example()
down to simply needing to call \Info::example()
?
This step is actually extremely straight forward - we add an alias. We're simply going to create an alias to our Facade class path \App\Services\Information\InfoFacade::class
and that alias is going to be \Info::class
.
How do we add aliases in Laravel?
- 1. We open
config/app.php
- 2. We scroll down to our
aliases
array. - 3. We add our alias.
// config/app.php
// config settings we scroll past
// add our 'Info' alias
'aliases' => [
'Info' => App\Services\Information\InfoFacade::class,
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
...
Now we can open up our terminal, run composer dumpautoload
then run php artisan tinker
and execute:
tinker> \Info::example();
And just like that, it works. That's a Laravel Facade folks.
Laravel Facades Review
- 1. Create a service class (Ex:
Info
) - 2. Create a facade class (Ex:
InfoFacade
) - 3. Bind our service class to the service container with any key (Ex: bind our Info class with a key of
Info
) - 4. Back in our
InfoFacade
class extendIlluminate\Support\Facades\Facade
create aprotected static
function calledgetFacadeAccessor
and return the key we bound our Service class to the service container with as a string from that function (Ex: returnInfo
) - 5. Open
config/app.php
and add an alias so we can access our Facade with prettier syntax (Ex:config/app.php
'saliases
array needs to have'Info' => App\Services\Information\InfoFacade::class
added) - 6. Run
composer dumpautoload
- 7. Use
\Info::example();
as your custom Facade.
Laravel Make Facades Package
- Alternatively, click that link above that says "Laravel Make Facades Package" - follow the instructions to install a package via composer and simply use the newly installed
php artisan make:facade
artisan command.
And, that - software engineers of the world - is how Laravel Facades work within Laravel as well as how to create your own. Feel free to watch the entire screencasts for a deeper dive into the details as well as walk through of the package that installs the php artisan make:facade
command to scaffold or generate custom facades without all of the extra leg work.