Laravel comes with very interesting features and one of the interesting features is Facade.A facade is design pattern in which some of the principles of its operation. Laravel comes with some Facades, In fact, you should have used them, but may not know what they are. Facades in Laravel are static agents like the IOC container class, which are simpler, easier to express, more testability and flexibility than traditional static methods.
What is Facade in Laravel?
A facade is actually a static proxy in a container or we can say it is a static way to call any object stored in the container anyway.
For Example,
1 2 3 4 5 6 7 | use Illuminate\Support\Facades\Cache; return Cache::get('key'); }); |
By default, the cache class does not have a get static method but you can use this with facade function. To operate the Cache get method, you must first Cache the class. So this class is in the app / config / app.php You can see that there is an alias array, which defines some of the framework comes with the class alias. You can see Cache class call in that you can find Illuminate \ Support \ Facades \ Cache class.
How you can use Facade in Laravel?
If you customize a class and put it in a container, you can call Facade in very simple way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | use Illuminate\Support\Facades\Facade; class Cache extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } } |
In above example, You just need to define a class to inherit the base class Illuminate\Support\Facades\Facade, and implement an abstract method getFacadeAccessor.
This method simply returns a string that gives the alias of the service container binding class. In fact, through the source can know that the object does not have to be placed in the container, you can return in the following way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | use Illuminate\Support\Facades\Facade; use Cache; class Cache extends Facade { /** * Get the component registration name * * @return string */ protected static function getFacadeAccessor() { return new Cache; } } |
How to achieve the Facade?
Let’s see the facade source code to understand Facade in base class.
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | abstract class Facade { /** * The application instance being facade. * * @var \Illuminate\Contracts\Foundation\Application */ protected static $app; /** * The resolved object instances. * * @var array */ protected static $resolvedInstance; /** * Get the root object behind the facade. * * @return mixed */ public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); } /** * Get the registered name of the component. * * @return string * * @throws \RuntimeException */ protected static function getFacadeAccessor() { throw new RuntimeException('Facade does not implement getFacadeAccessor method.'); } /** * Resolve the facade root instance from the container. * * @param string|object $name * @return mixed */ protected static function resolveFacadeInstance($name) { if (is_object($name)) { return $name; } if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } return static::$resolvedInstance[$name] = static::$app[$name]; } /** * Handle dynamic, static calls to the object. * * @param string $method * @param array $args * @return mixed * * @throws \RuntimeException */ public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); if (! $instance) { } return $instance->$method(...$args); } } |
This is core part of Facade in Laravel but there is more than that of the code, Let’s take a look at –callStatic method:
1 2 3 4 5 6 7 8 9 10 | public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); //an example if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); //Call method } |
This is a magic method in PHP which is called when a nonexistent method is called in a static way. The code is very simple to resolve the instance call method but here to note that one is the use of static keywords rather than self keywords, which involves a late static binding.
Look at the code of getFacadeRoot method and is from the container to resolve the object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static function getFacadeRoot(){ return static::resolveFacadeInstance(static::getFacadeAccessor()); } protected static function getFacadeAccessor(){ throw new RuntimeException('Facade does not implement getFacadeAccessor method.'); } protected static function resolveFacadeInstance($name){ if (is_object($name)) { return $name; } if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } return static::$resolvedInstance[$name] = static::$app[$name]; } |
Here, as per above code getFacadeAccessor method must be rewritten otherwise it will throw an exception. And then in resolveFacadeInstance method will first determine whether it is an object, if it is then directly return. So the above getFacadeAccessor method directly return to an object is also possible.
Then will determine whether the object has been resolved, if the analysis of the direct return, or from the container to resolve and then return, so that not only to achieve a single case, but also can improve performance. Get the object, that is, directly through the object to call the method:
1 2 3 | $instance->$method(...$args); //method call |
Conclusion
Facade design pattern in laravel is not difficult but documentation of facade method is not clear. There are lot of facades available in laravel. Here I have explained cache one. But you can use any facade pattern.
Comments (2)