Facades

The word 'facade' refers to a "superficial appearance or illusion of something," according to Dictionary.comopen in new window. In architecture, the term refers to the front of a building.

A facade in Laravel is a class that redirects static method calls to the dynamic methods of an underlying class. A facade's goal is to provide a memorable and expressive syntax to access an underlying class's functionality.

An example of a fluent API using a facade:

MessageFactory::sentBy($user)
    ->withTopic('Example message')
    ->withMessage($body)
    ->withReply($replyByFrank)
    ->create();
1
2
3
4
5

How a Facade Works

To learn more about facades and how they work, refer to the excellent Laravel documentationopen in new window.

Practically, it boils down to calling static methods on a Facade, which are "proxied" (redirected) to the non-static methods of an underlying class you have specified. This means that you're not actually using static methods. An example is discussed below, using a Calculator class as an example.

Creating a Facade

Let’s assume that we provide a Calculator class as part of our package and want to make this class available as a facade.

First create a Calculator.php file in the src/ directory. To keep things simple, the calculator provides an add(), subtract() and clear() method. All methods return the object itself allowing for a fluent API (chaining the method calls, like: ->add()->subtract()->subtract()->result()).

// 'src/Calculator.php'
<?php

namespace JohnDoe\BlogPackage;

class Calculator
{
    private $result;

    public function __construct()
    {
        $this->result = 0;
    }

    public function add(int $value)
    {
        $this->result += $value;

        return $this;
    }

    public function subtract(int $value)
    {
        $this->result -= $value;

        return $this;
    }

    public function clear()
    {
      $this->result = 0;

      return $this;
    }

    public function getResult()
    {
        return $this->result;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

In addition to this class, we’ll create the facade in a new src/Facades folder:

// 'src/Facades/Calculator.php'
<?php

namespace JohnDoe\BlogPackage\Facades;

use Illuminate\Support\Facades\Facade;

class Calculator extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'calculator';
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Finally, we register the binding in the service container in our service provider:

// BlogPackageServiceProvider.php
namespace JohnDoe\BlogPackage;

public function register()
{
  $this->app->bind('calculator', function($app) {
      return new Calculator();
  });
}
1
2
3
4
5
6
7
8
9

The end user can now use the Calculator facade after importing it from the appropriate namespace: use JohnDoe\BlogPackage\Facades\Calculator;. However, Laravel allows us to register an alias that can register a facade in the root namespace. We can define our alias under an “alias” key below the “providers” in the composer.json file:

"extra": {
    "laravel": {
        "providers": [
            "JohnDoe\\BlogPackage\\BlogPackageServiceProvider"
        ],
        "aliases": {
            "Calculator": "JohnDoe\\BlogPackage\\Facades\\Calculator"
        }
    }
}
1
2
3
4
5
6
7
8
9
10

Important: this feature is available starting from Laravel 5.5. With version 5.4 or below, you must register your facades manually in the aliases section of the config/app.php configuration file.

You can also load an alias from a Service Provider (or anywhere else) by using the AliasLoader singleton class:

$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('Calculator', "JohnDoe\\BlogPackage\\Facades\\Calculator");
1
2

Our facade now no longer requires an import and can be used in projects from the root namespace:

// Usage of the example Calculator facade
Calculator::add(5)->subtract(3)->getResult(); // 2
1
2