Home > Article > Backend Development > Detailed explanation of contracts in Laravel5, laravel5contracts_PHP tutorial
Let’s first take a look at the definition of contracts in the official documentation:
Laravel's Contracts are a set of interfaces that define the core services provided by the framework.
This means that Laravel's Contracts are a collection of core service interfaces provided by the framework.
In other words, each Contract is an interface, corresponding to a core service of the framework.
Then what’s the point? The explanation given by the official website is also very simple: using interfaces is for loose coupling and simplicity.
Let’s not talk about the big ideas first, let’s talk about some practical information and see how to use contract
First browse the contracts interface list:
Copy code The code is as follows:
IlluminateContractsAuthGuard
IlluminateContractsAuthPasswordBroker
IlluminateContractsBusDispatcher
IlluminateContractsCacheRepository
IlluminateContractsCacheFactory
IlluminateContractsConfigRepository
IlluminateContractsContainerContainer
IlluminateContractsCookieFactory
IlluminateContractsCookieQueueingFactory
IlluminateContractsEncryptionEncrypter
IlluminateContractsRoutingRegistrar
... There are too many, I am too lazy to post any more, it is in the official website manual. Let's take the IlluminateContractsRoutingRegistrar contract to demonstrate it.
First, open app/Providers/AppServiceProvider.php and pay attention to the register method:
Copy code The code is as follows:
public function register()
{
$this->app->bind(
'IlluminateContractsAuthRegistrar',
'AppServicesRegistrar'
);
}
$this->app is the Application object and also the container object. Through the $this->app->bind method we bind a class AppServicesRegistrar that implements the IlluminateContractsAuthRegistrar interface.
Note that IlluminateContractsAuthRegistrar is a contract. AppServicesRegistrar This class file is in app/Services/Registrar.php.
Then we look at the AppHttpControllersAuthAuthController controller class and see that it has a __construct constructor:
Copy code The code is 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 code The code is as follows:
use IlluminateContractsAuthGuard;
use IlluminateContractsAuthRegistrar;
Both of these are contracts, but let’s take Registrar here. We noticed that the interface type of $registrar is only specified through the parameter type, but when it is actually called, it is actually the AppServicesRegistrar class. This is the dependency. With the injection feature, Laravel will automatically search the container for classes or objects that implement the interface IlluminateContractsAuthRegistrar. If there are any, they will be taken out and passed to the constructor as actual parameters.
The entire usage process can actually be summarized into two steps:
Register an object that implements the contract interface with the container.
The constructor parameter type is specified as a contract interface class, and the framework will automatically find objects that meet the conditions.
So let’s talk about the benefits of contract.
Loose coupling
The official website gives an example to explain what tight coupling is and why the Contract interface can be loosely coupled.
Let’s take a look at the tightly coupled code first:
Copy code The code is as follows:
class Repository {
/**
* The cache.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param SomePackageCacheMemcached $cache
* @return void
*/
Public function __construct(SomePackageCacheMemcached $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 a detailed cache implementation SomePackageCacheMemcached is injected into the constructor. If you change Redis as the cache server or change the API method, you need to modify it. If the project is large, you don't know how many places need to be modified.
So, how does the Contract interface solve this problem? Please see the code:
Copy code The code is as follows:
use IlluminateContractsCacheRepository as Cache;
class Repository {
/**
* Create a new repository instance.
*
* @param Cache $cache
* @return void
*/
Public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}
Note that we use an interface for cache implementation, namely contract, IlluminateContractsCacheRepository, because it is just an interface, and you don’t need to care whether it is memcache or redis behind it.
Simplicity
If all services use interface definitions, it is easy to determine the functions required by a service, making it easier to maintain and expand, and the contract interface can also be regarded as a concise document that is easy to read.