Introduction
Facades
For the application of the IoC
service container provides a static interface class. Laravel comes with some Facades
, such as Cache
waiting. The facade of Laravel serves as a " static proxy " of the bottom class in the service container . Compared with traditional static methods, it can provide easier to test, more flexible, concise and elegant syntax during maintenance.
Explanation
In the context of this application which Laravel, one Facade
is a class, the class may be used to access an object from the container, this function is, Facade
inside the class definition. Laravel have any Facades Facades of your own definition, we will go to inherit Facade
this class.
You only need to implement a Facade class method: getFacadeAccessor
. To the container resolve
what comes out, there are methods to do this. Facade
The base class used __callStatic()
magic method, to be delayed resolved
, the call from the Facade object.
So, when you use Facade call, like this: Cache:get
, Laravel will serve Ioc container from inside resolves
the cache management class, and then go call this class get the above method. Laravel's Facades can go to locate services, it is a more convenient syntax to use Laravel's Ioc service container.
advantage
Facade has many advantages. It provides a simple, easy-to-remember syntax that allows us to use the features provided by Laravel without having to remember long class names. In addition, their unique use of PHP dynamic methods makes them easy test.
actual use
The following example calls Laravel's cache system. Look at this line of code, you may feel that this is a direct call to Cache
the class above is called a get
static method.
$value = Cache::get('key');
However, if you look at Illuminate\Support\Facades\Cache
this class, you will find here is simply not the static method get:
class Cache extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } }
The Cache class inherits the base class Facade, which defines a method called getFacadeAccessor (). Note that the job of this method is to return the name of an Ioc binding, here is the cache.
When the user referenced in this Cache any Facade
time on the static method, Laravel will go inside the container from the Ioc service resolves cache
this binding, and will go to perform on the object this method requested (this is get this method).
So, when we call Cache :: get, what it really means is this:
$value = $app->make('cache')->get('key');
Import Facades
Note that in the use of
facade
time, and if the controller which uses a namespace, you need to put into this category Facade namespace. All Facades are under the global namespace:
<?php namespace App\Http\Controllers; use Cache; class PhotosController extends Controller { /** * Get all of the application photos. * * @return Response */ public function index() { $photos = Cache::get('photos'); // } }
Create Facades
Only three things are needed to create Facade:
- An IoC binding.
- A Facade class.
- A Facade alias configuration.
In the following we define a class: PaymentGateway\Payment
.
namespace PaymentGateway;
class Payment { public function process() { // } }
We need to be able to resolve this class in the Ioc service container. So, first to add a Service Provider
binding:
App::bind('payment', function() { return new \PaymentGateway\Payment; });
The best way to register is to bind to create a new Service Provider
, name it PaymentServiceProvider
, and then bind it to register
the method. Configuring laravel go in config/app.php
to load your configuration file inside Service Provider
.
The next step is to create your own Facade
class:
use Illuminate\Support\Facades\Facade; class Payment extends Facade { protected static function getFacadeAccessor() { return 'payment'; } }
Finally, if you prefer, you can go to Facade
add an alias, put config/app.php
the configuration file in the aliases
array.
You can call on to an instance of class Payment of process
this method has. like this:
Payment::process();
When to use Facade
note
In use Facade
there are caveats, the main danger is a class scope creep. Because Facade
it is so easy to use and does not require injection, using too much in a single class Facade
will make the class easy to get bigger and bigger. Using dependency injection will alleviate such problems, because a huge constructor will make it easy to judge that the class is getting bigger. Therefore, Facade
pay special attention to the size of the class when using it in order to control its limited responsibilities.
Note: When building a third-party extension package that interacts with Laravel, it is best to inject the Laravel contract instead of using the facade. Because the extension package is built outside of Laravel, you will not be able to access Laravel's facade test helper functions.
Facade vs. dependency injection
The biggest advantage of dependency injection is that it can replace the implementation of the injected class, which is useful when testing, because you can inject a mock or stub and assert different methods on the stub.
But simulation or stubs on static class methods won't work. However, since Facade
dynamic methods are used to proxy object method calls resolved in the service container, we can also test the facade as if we were testing injection class instances. For example, given the following route:
use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key'); });
We can write tests to verify this Cache::get
method to the way we expect to be called:
use Illuminate\Support\Facades\Cache; /** * A basic functional test example. * * @return void */ public function testBasicExample() { Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value'); }
Facade vs. helper function
In Facade
addition, Laravel has built-in many auxiliary functions for performing common tasks, such as generating views, triggering events, assigning tasks, and sending HTTP responses. Many auxiliary functions provide appropriate and Facade
the same function, for example, the following Facade
call and auxiliary function calls are equivalent:
return View::make('profile'); return view('profile');
Facade
There is no substantial difference between it and the auxiliary function. When using the auxiliary function, you can test them like the corresponding facade. For example, given the following route:
Route::get('/cache', function () { return cache('key'); });
In calling the bottom, cache
the method will be to call Cache Facade
on the get
method, therefore, even though we use this helper function, we can write the following tests to verify the method parameters and the way we expect to be called:
use Illuminate\Support\Facades\Cache; /** * A basic functional test example. * * @return void */ public function testBasicExample() { Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value'); }
How Facade works
In the Laravel application, it Facade
is a class that provides access to objects in the container. The principle of the mechanism of Facade
implementation class. Laravel own Facade
, as well as custom facade we create will inherit from Illuminate\Support\Facades\Facade
the base class. You can refer to the Facade implementation principle
Facade
Class need only implement one method: getFacadeAccessor
. It is getFacadeAccessor
method defines what parsed from the container, then Facade
the base class use the magic method __callStatic()
invocation from your analytical objects in the facade.
The following example, we will call the Laravel
caching system, after browsing the code, you might think we call a Cache
static method get
:
<?php
namespace App\Http\Controllers; use Cache; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 为指定用户显示属性 * * @param int $id * @return Response */ public function showProfile($id) { $user = Cache::get('user:'.$id); return view('profile', ['user' => $user]); } }
Note that we introduced it at the top Cache Facade
. The facade as a proxy to access the underlying Illuminate\Contracts\Cache\Factory
implementation of the interface. All our calls to the facade will be passed to the underlying instance of the Laravel cache service.
If we look at Illuminate\Support\Facades\Cache
the class source code, you will be found and no static methods get
:
class Cache extends Facade
{ /** * 获取组件注册名称 * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } }
Cache Facade
Inherit Facade
the base class and set the getFacadeAccessor
method of work which is to return the alias service binding class vessel, when the user references Cache
any static methods class, Laravel from the service container resolved in cache
bind, and then call on all parsed object Request method (get in this case
)
Facade category list
Below is a list of each facade and its corresponding low-level class, which is a useful tool for going deep into the API documentation for a given root facade. The service container binding key is also included:
Facade Facade |
class class |
Service container binding |
---|---|---|
App | Illuminate\Foundation\Application | app |
Artisan | Illuminate\Contracts\Console\Kernel | artisan |
Auth | Illuminate\Auth\AuthManager | auth |
Blade | Illuminate\View\Compilers\BladeCompiler | blade.compiler |
Bus | Illuminate\Contracts\Bus\Dispatcher | |
Cache | Illuminate\Cache\Repository | cache |
Config | Illuminate\Config\Repository | config |
Cookie | Illuminate\Cookie\CookieJar | cookie |
Crypt | Illuminate\Encryption\Encrypter | encrypter |
DB | Illuminate\Database\DatabaseManager | db |
DB(Instance) | Illuminate\Database\Connection | |
Event | Illuminate\Events\Dispatcher | events |
File | Illuminate\Filesystem\Filesystem | files |
Gate | Illuminate\Contracts\Auth\Access\Gate | |
Hash | Illuminate\Contracts\Hashing\Hasher | hash |
Just | Illuminate\Translation\Translator | translator |
Log | Illuminate\Log\Writer | log |
Illuminate\Mail\Mailer | mailer |
|
Notification | Illuminate\Notifications\ChannelManager | |
Password | Illuminate\Auth\Passwords\PasswordBrokerManager | auth.password |
Queue | Illuminate\Queue\QueueManager | queue |
Queue(Instance) | Illuminate\Contracts\Queue\Queue | queue |
Queue(Base Class) | Illuminate\Queue\Queue | |
Redirect | Illuminate\Routing\Redirector | redirect |
Redis | Illuminate\Redis\Database | redis |
Request | Illuminate\Http\Request | request |
Response | Illuminate\Contracts\Routing\ResponseFactory | |
Route | Illuminate\Routing\Router | router |
Schema | Illuminate\Database\Schema\Blueprint | |
Session | Illuminate\Session\SessionManager | session |
Session(Instance) | Illuminate\Session\Store | |
Storage | Illuminate\Contracts\Filesystem\Factory | filesystem |
URL | Illuminate\Routing\UrlGenerator | url |
Validator | Illuminate\Validation\Factory | validator |
Validator(Instance) | Illuminate\Validation\Validator | |
View | Illuminate\View\Factory | view |
View(Instance) | Illuminate\View\View |
Author: Iraq Summer
link: https: //www.jianshu.com/p/a96715975d4e
Source: Jane books
are copyrighted by the author. For commercial reproduction, please contact the author for authorization, and for non-commercial reproduction, please indicate the source.