Laravel Facade — I can do it too!

Syed Sirajul Islam Anik
5 min readNov 16, 2017

--

http://images.phpgang.com/2016/03/An-overview-of-Laravel-5-Facades-through-the-Session-and-Auth-facades.jpg

After a long time, I just started writing once again. Still got 5 posts in the pipeline. Lazy enough to write and publish. But I was thinking about writing facade for a long time. Facade sounds like a jargon while it’s not. It’s just an OOP implementation. Before you read more, I would suggest you to know OOP well. I was thinking about writing on “OOP with PHP”. But OOP is a huge topic that requires a lots of time. Let’s just focus on today’s article. Before I write about Laravel’s facade, I will tell you about some PHP OOP tweaks.

N.B:

  1. I needed an image. Collected from the internet. Doesn’t mean it is based on Laravel 5. The facade for Laravel 4 and 5 are the same.
  2. I don’t want to argue over Laravel’s Facade is actually not facade, it’s a proxy pattern.

PHP OOP tweaks

  1. __call magic method is called if the class doesn’t have the called method.
  2. __callStatic magic method is called if there is no static method exist with the called name.
  3. Class’s method overrides any inherited method. — Trait’s or Class’s method.
  4. When overriding a method, the access modifier should be more open than the parent class.
  5. Method chaining sounds fancy, it’s nothing but returning the $this from the method so that you can call the another method of the same object.

What to do if I want to make a Facade?

  1. To use/implement the facade, in your facade class you’ve to extend the Illuminate\Support\Facades\Facade class.
  2. In your class, you’ll have to implement getFacadeAccessor method.
  3. From this method, you’ll either have to return a concrete object or a string which is resolved somewhere else.

How this facade gets resolved?

// MyFacade is an extension of Facade class
MyFacade::giveMeSomething();

When you call MyFacade class with a static method giveMeSomething, it finds that your class does not have that static method. So it transfer the call to __callStatic magic method (PHP tweaks#2). This method is written on Base Facade class that is inherited to your facade class. Within that method, it calls another static method getFacadeRoot. This method again calls another static method resolveFacadeInstance where it is checked if the name is an object or a string. If your getFacadeAccessor did return a concrete object then it will return your object. Otherwise, it will check if the string with that name has already resolved an instance or not. If the name has resolved an instance earlier, then that instance will be returned, otherwise it will try to fetch the matching instance from your Laravel Application instance and will be returned.

Before we create our own facade, let’s have a look at how laravel handles facade. Let’s just have a look at Illuminate\Support\Facades\Auth class which extends Facade class. As we know, to use Facade you’ve to implement a method which is getFacadeAccessor, that class implements that method and returns a string. As it returned string, this name is resolved somewhere else. This string ‘auth’ is resolved inside Illuminate\Auth\AuthServiceProvider which returns a concrete object. For simplicity, just ignore the other code. Stick to the $this->app->singleton method.

So, when the following code is executed, the following scenario happens:

// ...
$user = Auth::user();
// ...
  1. Auth Facade doesn’t have the user method. __callStatic method is called.
  2. __callStatic asks for an instance, as getFacadeAccessor returns a string, tries to get the concrete object from Laravel application. — Explained in how facade is resolved section.
  3. Gets the concrete object from AuthServiceProvider and returns an instance of AuthManager.
  4. __callStatic method has the instance of AuthManager and on that instance, it calls the user method and returns to the callee. AuthManager class somehow manages the user method. To know how it manages the user method, read my another article — “Laravel Auth — how does it happen?

Wait, How can I create a Facade, huh?

If you’ve understood what I have said so far in this article, you can implement your own facade by yourself. But, Let us do it together if you didn’t get it yet.

  • Create a class which will be actually called by the facade.
<?php
namespace App\Extensions;
// this class will be called from facade
Class Operation
{
public function add ($a, $b){
return $a + $b;
}

public function subtract ($a, $b) {
return $a - $b;
}
}
  • Create a class that extends Facade.
<?php
namespace App\Extensions;
use Illuminate\Support\Facades\Facade;class OperationFacade extends Facade
{
protected static function getFacadeAccessor() {
// either 1.
// return 'operation';
// otherwise,
return new Operation();
}
}
  • If you did return a string instead of an object from your OperationFacade::getFacadeAccessor, bind the name in your any of the registered service providers (custom or shipped) or inside the bootstrap/app.php (not a good way to do it)
<?php
namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
public function boot () {
$this->app->bind('operation', function() {
return new Operation();
});
}
}
  • If you don’t want to add to any service provider
<?php
// bootstrap.php
/// ...
// after the Application instance
$app->bind('operation', function() {
return new Operation();
});
// ...
return $app;
  • Now you can call this from anywhere in your code
<?php
// web.php
Route::get('test-facade', function(){
$a = OperationFacade::add(10, 30);
$b = OperationFacade::subtract(20, 40);
return [$a, $b];
});
  • call the route and you’ll show it returns 40 and -20.

Facade cons

Facade sounds fancy but it adds overhead to your code. If it’s not necessary then it is recommended to ignore creating new facades. Just think that your code always loads a class, calls 3 static methods just to resolve an instance!! These costs much when you’re building a rich application with heavy traffic. Each second matters. So, try to avoid using facades.

So far I tried to make you understand about how facade works and how you can create one of your own. Hope you did learn by reading the article (if you didn’t know). If you think there is something wrong in this article or is misleading with the information, please feel free to let me know.

Happy Coding.

--

--

Syed Sirajul Islam Anik

software engineer with "Senior" tag | procrastinator | programmer | !polyglot | What else 🙄 — Open to Remote