This is the 14th day of my participation in the August Text Challenge.More challenges in August
Before, I wrote an article about Laravel improving the efficiency of DB query. After forwarding it to the group, some people questioned me and said, “Laravel is the framework he used several years ago, I didn’t expect that there are still people using it now.”
Nani, what do you mean? Don’t forget PHP is the best language!
Personally, Laravel is a very elegant development framework: elegant design patterns, powerful feature implementations, easy extensions, constant release updates, and most importantly, the best technology development community to date, in my opinion.
I have to make a Call for Laravel.
Laravel released version 8.0 on September 8, 2020. Laravel is scheduled to release version 9.0 on January 25, 2022.
Here I would like to introduce the new features of the latest Laravel release (8.0) :
Laravel 8 with the introduction of Laravel Jetstream, model factory classes, Migration compression, queue batching, improved rate limiting, queue improvements, dynamic Blade components, Tailwind paging view, Time test Assistant, artisan Serve improvements, Improvements to the event listener, along with various other bug fixes and usability improvements, continue to improve Laravel 7.x.
This article focuses on the Contracts of Laravel
Introduction to the
Laravel’s contract is a set of interfaces that are provided by the framework and define the core services.
For example, the illuste\Contracts\Queue\Queue contract defines the methods needed for queuing jobs, and the illuste\Contracts\Mail\Mailer contract defines the methods needed to send Mail.
Each contract has a corresponding implementation provided by the framework.
For example, Laravel provides a queue implementation with various drivers, a mailer implementation supported by SwiftMailer, and more.
All Laravel contracts exist in their respective GitHub repositories.
This provides a quick reference point for all available contracts, as well as a separate package that can be used by developers.
Contracts vs. Facades
Laravel’s Facades and helper functions provide an easy way to leverage Laravel services by resolving contracts from a service container without type hints.
In most cases, each Facade has an equivalent contract.
Unlike Facades, which do not require us to introduce them into a class’s constructor, contracts allow us to define explicit dependencies for classes. Some developers prefer to define their dependencies explicitly in this way, and so prefer to use contracts; Other developers enjoy the convenience of a Facade.
Both have their own advantages and disadvantages, depending on your needs and application scenarios.
Tip: Whether we prefer Facads or contracts, most apps work fine. However, if you are building a package, use of contracts should be strongly considered because they are easier to test in the context of a package.
When to use a contract
As discussed elsewhere, many decisions to use contracts or Facades will depend on personal preferences and the preferences of the development team.
Both contracts and Facades can be used to create powerful and well-tested Laravel applications. As long as we focus on the single responsibility of the class, the actual difference between using contracts and Facades is small.
However, we may still have a few questions about the contract. For example, why use interfaces? Isn’t it more complicated to use interfaces?
Let’s boil the reasons for using interfaces down to two: loose coupling and simplicity.
Loose coupling
First, let’s review some tightly coupled code for caching. Consider the following:
<? php namespace App\Orders; Class Repository {/** * protected $cache; /** * create a new repository instance ** @param \SomePackage\Cache\Memcached $Cache * @return void */ public function __construct(\SomePackage\Cache\Memcached $cache) { $this->cache = $cache; Public function find($ID) {if ($this->cache->has($ID)) {//} }}Copy the code
In this class, the code is tightly coupled to a given cache. It is tightly coupled because we rely on the specific caching classes provided by the package vendor. If the API of this package changes, our code must change too.
Similarly, if we wanted to replace the underlying caching technology (Memcached) with another technology (Redis), we would have to modify our code base again. Our code base should not have too much knowledge about who is providing them with data or how they are providing it.
Instead of this approach, we can improve our code by relying on a simple, vendor-neutral interface:
<? php namespace App\Orders; use Illuminate\Contracts\Cache\Repository as Cache; Class Repository {/** * protected $cache; Public function __construct(Cache $Cache) {$this-> Cache = $this-> Cache = $cache; }}Copy the code
Right now, this code is not coupled to any particular vendor.
Because the contract package contains no implementation and has no dependencies, we can easily write an alternative implementation of any given contract, allowing us to replace the cached implementation without modifying any code that consumes the cache.
simplicity
When all of Laravel’s services are neatly defined in simple interfaces, it is easy to identify the functionality provided by a given service. Contracts are a concise document of the framework’s capabilities.
In addition, our code is easier to understand and maintain when we rely on simple interfaces. Instead of keeping track of what methods are available in large, complex classes, we can refer to a simple, clean interface.
How to use contracts
So how do you implement contracts? It’s actually quite simple.
Many of the classes in Laravel are resolved through the service container, including controllers, event listeners, middleware, queue tasks, and even route closures. Therefore, to implement the contract, we simply “type hint” interface in the constructor of the class being parsed.
For example, look at this event listener:
<? php namespace App\Listeners; use App\Events\OrderWasPlaced; use App\Models\User; use Illuminate\Contracts\Redis\Factory; Class CacheOrderInformation {/** * Redis factory implementation */ protected $Redis; Public function __construct(Factory $redis) {$this->redis = $redis; @param OrderWasPlaced $event @return void */ public function handle(OrderWasPlaced $event) {//}}Copy the code
When the event listener is parsed, the service container reads the type hint on the constructor of the class and injects the appropriate value.
Gorgeous dividing line
For more on Laravel, check out my column: Server Development from Beginner to Master
Recommended reading
-
I’m still working on Laravel? Don’t forget PHP is the best language. (2) Laravel Jetstream and model Factory classes
-
I’m still working on Laravel? Don’t forget PHP is the best language. (3) Migration compression, queue batch processing, improve rate limit
-
I’m still working on Laravel? Don’t forget PHP is the best language. (4) Optimization of maintenance mode
-
I’m still working on Laravel? Don’t forget PHP is the best language. (5) Dynamic Blade event listener optimizes event test assistant
-
I’m still working on Laravel? Don’t forget PHP is the best language. (6)
-
I’m still working on Laravel? Don’t forget PHP is the best language. (7) Laravel Installation Guide
-
I’m still working on Laravel? Don’t forget PHP is the best language. (8) Directory structure
-
I’m still working on Laravel? Don’t forget PHP is the best language. (9) Deployment of Laravel
-
I’m still working on Laravel? Don’t forget PHP is the best language. (10) Introduction of Laravel’s request cycle
-
I’m still working on Laravel? Don’t forget PHP is the best language. (11) Laravel service container
-
I’m still working on Laravel? Don’t forget PHP is the best language. (12) Service providers
-
I’m still working on Laravel? Don’t forget PHP is the best language. (13) Laravel frame the most important Facades
Last but not least
Technical group please come here. Or add my wechat account wangzhongyang0601 to learn together.