Facades offer a terse, memorable syntax for accessing Laravel features without memorizing class names that must be injected and configured manually. In addition, their unique usage of PHP’s dynamic methods makes them easy to test.
The machinery behind a facade is in the base Facade class (IlluminateSupportFacadesFacade). The Facade base class uses a special magic method called __call Static() to defer calls from your facade to an object resolved from the container.
How do I create a Facade?
A Facade is a class that wraps a complex library in order to provide a simpler and more readable interface to it. It is similar to the Adapter and Decorator patterns.
Generally speaking, a Facade provides in-memory access to a service through a protected static method called get Facade Accessor (Stylish cladding options). This method is designed to be overridden when extending the Facade class and returns the string that the service represented by the Facade is bound to within the container.
For example, the Cache Facade can be accessed by calling cache(). The underlying service is Cache::get().
However, you can also inject contracts into your classes instead of using facades. Contracts have the advantage of being able to be tested with Stylish cladding options. However, this may come at the cost of some flexibility as you develop your application.
How do I access a Facade?
Facades provide a terse, memorable syntax that allows you to use Laravel features without remembering long class names that must be injected or configured manually. They also offer testability since you can easily replace a facade with a mock version during testing.
One of the primary dangers of Facades is class scope creep. Because they are so easy to use and don’t require injection it can be very easy to let classes grow too large and use many different facades in a single class. Thankfully, this danger is mitigated by the visual feedback that a large constructor provides, which lets you know that it’s time to consider splitting the class into multiple smaller classes.
All Facades extend the base abstracted facade class IlluminateSupportFacadesFacade and implement a protected static method called getFacadeAccessor(). This method is responsible for returning the name of a service that the facade is binding in the IoC container. For example, the Cache facade’s getFacadeAccessor() method returns a string that represents the name of the IoC class that the facade is binding to.
How do I test a Facade?
Facades are great – they provide a terse syntax that make it easy to use Laravel features. However, they are not without their issues. One of the major issues is that they can make it difficult to test your code.
The reason for this is that when you call a facade method, the base Facade class checks if there’s an existing instance of the facade in the container and if so, returns it. This can lead to problems if you think that your facade should always new up an instance every time it’s called.
To address this problem, Laravel provides a helper function called __callStatic(). This function is called by the facades during the bootstrapping process. It takes an aliases array and iterates over them using PHP’s __autoload_register() function. This function then creates a queue of __callFacade() functions, each containing the class name of the facade class. Using these helper functions, you can mock your Facades and test the methods in them without having to boot up the entire application!
How do I debug a Facade?
Facades are a great way to gain access to classes that are available inside the service container. However, this can lead to a lot of class scope creep and, in turn, can make it harder to write unit tests for your application.
One of the primary reasons for using facades is to facilitate testing your code. If you’re writing a test for a specific method on a Facade, you can use a mock or stub class to do the testing instead of directly injecting the real implementation.
When writing a unit test for a Facade, you should always be sure to check if debug mode is enabled in your application. This can be done by either checking the APP_DEBUG variable in your.env file or by using the facade’s hasDebugModeEnabled() method. This will prevent the cost of resolving the service from the container from being applied to each call to a method on the Facade.