How to Make Laravel Facades (Tutorial)

Clean Code Studio - Aug 3 '21 - - Dev Community

Twitter Follow


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";
   }
}

Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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 called getFacadeAccessor() that returns the key in our service container that we're going to use to bind our Info Service class to the Service Container.
namespace App\Services\Information;

use Illuminate\Support\Facades\Facade;

class InfoFacade extends Facade
{
   protected static function getFacadeAccessor()
   {
       return 'Info';
   }
}
Enter fullscreen mode Exit fullscreen mode
  • 3. Now, we need to bind our Info Service class to the Service Container with a key of Info since Info is what is returned by the getFacadeAccessor method in the InfoFacade

<?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();
        });
    }

}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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,
      ...
Enter fullscreen mode Exit fullscreen mode

Now we can open up our terminal, run composer dumpautoload then run php artisan tinker and execute:

tinker> \Info::example();
Enter fullscreen mode Exit fullscreen mode

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 extend Illuminate\Support\Facades\Facade create a protected static function called getFacadeAccessor and return the key we bound our Service class to the service container with as a string from that function (Ex: return Info)
  • 5. Open config/app.php and add an alias so we can access our Facade with prettier syntax (Ex: config/app.php's aliases array needs to have 'Info' => App\Services\Information\InfoFacade::class added)
  • 6. Run composer dumpautoload
  • 7. Use \Info::example(); as your custom Facade.

Laravel Facades Summarized


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.

Structural Design Patterns

The Facade Design Pattern

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .