How to Create a Facade in Laravel 4

There are three components to generating a Facade:

  1. The Facade Root, the underlying class the Facade calls methods on.
  2. The Facade Class, which tells Laravel which registered (underlying) class it pertains to
  3. A Service Provider, which registers the underlying class in the App container

The Use Case

Let's say we have a class which we want to generate a Facade for. This class might be Fideloper\Example\UnderlyingClass.

<?php namespace Fideloper\Example;

class UnderlyingClass {

    public function doSomething()
    {
        echo 'Doing something!';
    }

}

Let's continue and pretend you want to create a Facade for that class, so that developers can access it with calls such as:

UnderlyingClass::doSomething();

The Implementation

To start, you need to make a Facade class:

<?php namespace Fideloper\Example\Facades;

use Illuminate\Support\Facades\Facade;

class UnderlyingClass extends Facade {

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'underlyingclass'; }

}

Setting the Facade accessor to 'underlyingclass' tells Laravel that the Facade class is looking for $app['underlyingclass'].

Next, you need to connect your underlying class with your Facade. You can do this within a Service Provider. The Service Provider will do two things:

  1. Bind 'underlyingclass' to our UnderlyingClass object. As mentioned above, this connects the Facades accessor 'underlyingclass' to the binded $app['underlyingclass'].
  2. Create the Alias used to access the underlying class UnderlyingClass. This alias is registered to the Facade we created, which in turn is set to access our underlying class. Get it? Good. Note: Setting the alias in the Service Provider is a shortcut so you do not have to bother to add an entry to the Aliases in the app/config/app.php. In my opinion, adding the alias in the service provider is easier for developers - Simply include your service provider in app/config/app.php and continue!

Here is the Service Provider:

<?php namespace Fideloper\Example;

use Illuminate\Support\ServiceProvider;

class ExampleServiceProvider extends ServiceProvider {

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        // Register 'underlyingclass' instance container to our UnderlyingClass object
        $this->app['underlyingclass'] = $this->app->share(function($app)
        {
            return new Fideloper\Example\UnderlyingClass;
        });

        // Shortcut so developers don't need to add an Alias in app/config/app.php
        $this->app->booting(function()
        {
            $loader = \Illuminate\Foundation\AliasLoader::getInstance();
            $loader->alias('UnderlyingClass', 'Fideloper\Example\Facades\UnderlyingClass');
        });
    }
}

The last step is to register your Service Provider in the app/config/app.php file with the other providers, you'll be able to use your new Facade!

'providers' => array(

    ... Other Providers Above ...
    'Illuminate\Workbench\WorkbenchServiceProvider',

    'Fideloper\Example\ExampleServiceProvider',

),

And that's it! You can use your Facade, just as you wanted:

UnderlyingClass::doSomething();
comments powered by Disqus