Let's take a look at the definition of contracts in the official documentation:
Laravel ' s contracts is a set of interfaces that define the core services provided by the framework.
This means that Laravel's contracts is a collection of core service interfaces provided by the framework.
In other words, each contract is an interface that corresponds to a framework core service.
And what does it mean? The explanation on the website is simple: The interface is used for loose coupling and simplicity.
First of all, do some dry goods, to see how to use Contract
First, browse the following list of contracts interfaces:
Copy the Code code as follows:
Illuminate\contracts\auth\guard
Illuminate\contracts\auth\passwordbroker
Illuminate\contracts\bus\dispatcher
Illuminate\contracts\cache\repository
Illuminate\contracts\cache\factory
Illuminate\contracts\config\repository
Illuminate\contracts\container\container
Illuminate\contracts\cookie\factory
Illuminate\contracts\cookie\queueingfactory
Illuminate\contracts\encryption\encrypter
Illuminate\contracts\routing\registrar
...... Too much, too lazy to continue to post, the official website of the manual. Let's take illuminate\contracts\routing\registrar this contract to demonstrate it.
First, open the app/providers/appserviceprovider.php and note the Register method:
Copy the Code code as follows:
Public Function Register ()
{
$this->app->bind (
' Illuminate\contracts\auth\registrar ',
' App\services\registrar '
);
}
$this->app is a Application object and a container object, we bind an implementation by $this->app->bind method illuminate\contracts\auth\ The class App\services\registrar of the Registrar interface.
Note that Illuminate\contracts\auth\registrar is a contract. App\services\registrar This class file is in app/services/registrar.php.
Then we look at App\http\controllers\auth\authcontroller the controller class and see that it has the __construct constructor:
Copy the Code code as follows:
Public function __construct (Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->middleware (' guest ', [' except ' = ' getlogout ']);
}
It has two parameters, and the corresponding class namespace can be seen at the beginning of the script:
Copy the Code code as follows:
Use Illuminate\contracts\auth\guard;
Use Illuminate\contracts\auth\registrar;
Both of these are contract, but here we take registrar, we notice that the interface type is only indicated by the parameter type, but actually the app\services\registrar of the class when actually called. This is the feature of dependency injection, Laravel automatically searches the container for the class or object that implements the interface Illuminate\contracts\auth\registrar, and some of it is taken out as the actual parameter to the constructor.
The whole process can actually be summed up in two steps:
Registers the object that implements the contract interface with the container.
The constructor parameter type is specified as the contract interface class, and the framework automatically finds objects that match the criteria.
So, again, the benefits of contract.
Loose coupling
The official website gives an example of what is tight coupling and why the contract interface can be loosely coupled.
First look at the tightly coupled code:
Copy the Code code as follows:
<?php namespace App\orders;
Class Repository {
/**
* the cache.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param \somepackage\cache\memcached $cache
* @return void
*/
Public function __construct (\somepackage\cache\memcached $cache)
{
$this->cache = $cache;
}
/**
* Retrieve an Order by ID.
*
* @param int $id
* @return Order
*/
Public function Find ($id)
{
if ($this->cache->has ($id))
{
//
}
}
}
You can see that the constructor has injected a detailed cache implementation \somepackage\cache\memcached, if you change Redis as a cache server or changed the API method, you need to modify, and if the project is large, you do not know how many places need to be modified.
So, how does the contract interface solve this problem? Please look at the code:
Copy the Code code as follows:
<?php namespace App\orders;
Use Illuminate\contracts\cache\repository as Cache;
Class Repository {
/**
* Create a new repository instance.
*
* @param Cache $cache
* @return void
*/
Public function __construct (Cache $cache)
{
$this->cache = $cache;
}
}
Note that the cache implementation we use an interface, that is, contract,illuminate\contracts\cache\repository, because it is just an interface, does not need to care about the memcache or redis behind.
Simplicity of
If all services use the interface definition, it is easy to determine the functionality required by a service, easier to maintain and extend, and the contract interface can be viewed as a concise document for readability.