Foreword
As we may know, PHP is a popular language among web developers and Backend. When mentioning PHP one cannot help but mention Laravel Framework. Laravel is an open source framework, created by Taylor Otwell . Laravel is designed based on the MVC pattern. Currently Laravel has released version 7.x has changed a lot compared to the first version from June 9, 2011.
I personally find that when learning any Framework, the first thing that we must know is which Frameworks there are Design Patterns. And Laravel, too, in its documents section, the author also cleverly arranges some Design Pattern on the first place and then the technicals in Laravel. Before going to list some Design Patterns you need to know in Laravel. Make sure you understand the concept of Design Pattern.
An easy-to-understand definition of a Design Pattern is as follows:
- Design Pattern is a technique in object-oriented programming that programmers and researchers summarize standard designs for programming with common patterns.
- Design Pattern is not a specific language, all programming languages or its framework can apply Design Pattern.
- Design Pattern helps projects to expand, limit bugs and maintain efficiency.
- Design Pattern helps to unify the common code way so programmers will work effectively in groups to avoid having each person type 1 code.
main content
1. Laravel request lifecycle
Any website that wants to run must have a web server, be it apache, IIS, or nginx, … The popular web server used today is Nginx, this is a reverse proxy server. Open source for HTTP, HTTPS, SMTP, POP3 and IMAP protocols, as well as a load balancer, HTTP cache and web server. Below is an example of config of nginx to run a web code using PHP – Laravel.
1 2 3 4 5 6 7 8 9 10 11 12 | server <span class="token punctuation">{</span> root /deploy/blog/current/public <span class="token punctuation">;</span> index index.php index.html index.htm <span class="token punctuation">;</span> server_name quy.blog.me <span class="token punctuation">;</span> try_files <span class="token variable">$uri</span> <span class="token variable">$uri</span> / @rewrite <span class="token punctuation">;</span> location @rewrite <span class="token punctuation">{</span> rewrite ^/ <span class="token punctuation">(</span> .* <span class="token punctuation">)</span> $ /index.php?_url <span class="token operator">=</span> / <span class="token variable">$1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Most people before learning about Laravel, they already know the MVC pattern (Model – View – Controller). A Laravel request will work based on the same model. Users make requests on the browser, web server (nginx) will fill the request into public/index.php
you can see in the above config. The index.php
file will be the input of the project requests. The bootstrapper in the bootstrap folder helps to configure error handling, log configuration, identify application environment, and perform other tasks right before the request is processed. Next, incoming requests are sent either to the HTTP kernel or the console kernel, depending on the type of request coming into the application. These two kernels serve as the central part of the request flow coordination. For now, let’s just focus on the HTTP kernel, which is located in app/Http/Kernel.php
. In Kernel.php
is the place to declare the middleware, the place to receive the requests and return the responses. One of the most important kernel initialization operations is to load service providers. All service providers are configured in the config / app.php file in the $ providers array. First, the register function will be called on all providers, and then, once the providers have been fully registered, the boot function will be called. Finally, the request will be routed by the router to the controller and issue the views to the user (response).
2. Dependency Injection
Dependency Injection is a design pattern used to try to achieve dependency between objects when there is a dependency relationship between one object and another.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Comment</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$user</span> <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token variable">$comment</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$user</span> <span class="token punctuation">,</span> <span class="token variable">$comment</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">user</span> <span class="token operator">=</span> <span class="token variable">$user</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">comment</span> <span class="token operator">=</span> <span class="token variable">$comment</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$post</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Post</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Comment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
We can easily understand Dependency Injection in this case that is: Instead of having to initialize multiple instances of User and Comment objects in Post objects, we only need to inject those instances into the Post class through the __contructor
magic function. or __setter
. Instances that the Post class uses of User and Comment are dependencies.
3. Service Container
The Service Container in Laravel manages the dependency class and performs dependency injection
Binding: Register a class or interface with the container.
Simple Binding:
1 2 3 4 | <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">bind</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HelpSpotAPI'</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name"> HelpSpot API</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">make</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HttpClient'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Binding A singleton:
1 2 3 4 | <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">singleton</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HelpSpotAPI'</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name"> HelpSpot API</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">make</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HttpClient'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Resolving: Retrieving instances from containers.
The function in resolve that we can use is: make
1 2 | <span class="token variable">$api</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">make</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HelpSpotAPI'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
or resolve
1 2 | <span class="token variable">$api</span> <span class="token operator">=</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HelpSpotAPI'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
In Service Container, you need to master some concepts of Singleton binding
, Instance binding
, Interface binding
, … Singleton binding: Instance will only be resolved once, subsequent calls will not create a new instance but reuse the instance. resolved from earlier. Instance binding: Similar to Singleton binding
, you bind an instance to a service container. Each time it is retrieved, it will be retrieved. Interface binding: When we type-hint interface in __contruct()
or method, they will get corresponding implementaion when we register in Service Container. That is the process of binding (registering a class or an interface vs Container) and resolving (taking) an instance from the Container.
4 Service Provider
The declarative place for binding the Service Containers. Service Providers are declared at config/App.php
In Service Provider, there are 2 function register
and boot
.
register: Where to register the service containers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token comment">/** * Register the upload manager. * * @return void */</span> <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function">register</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">singleton</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'upload'</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">tap</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">UploadManager</span> <span class="token punctuation">(</span> <span class="token variable">$app</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$manager</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">registerHandlers</span> <span class="token punctuation">(</span> <span class="token variable">$manager</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
boot: The place to allow access to the services that are registered in the register
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment">/** * Bootstrap services. * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">make</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'upload'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">cycle</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">callListeners</span> <span class="token punctuation">(</span> <span class="token variable">$event</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
5. Facades
Have you ever seen and used a lot of facades. It is declared in the alias array in config/app.php
. The purpose of this is to enable us to use in our project under a short name, instead of having to write their full namespace.
6. Contracts
Laravel Contracts is a set of interfaces that declare core services provided by the framework. For example, the contract Illuminate Contracts Queue Queue declares the methods needed for queue processing jobs, while Illuminate Contracts Mail Mailer declares the methods needed to send emails. Refer to contracts at illuminate / contracts .
7. Repository
The Repository Pattern is an intermediary layer between the Business Logic and Data Access layer, which makes data access tighter and more secure. The Repository acts as a connection layer between the Business layer and the Model of the application. Understandably, when t want to access data from the database, instead of writing processing code in the controller, we create a folder called Repository and then write the processing code here. Then we just inject it through __construct
.
Why should I use the repository:
- The code follows the design pattern so it is easy to maintain.
- Increase the security and clarity of the code.
- Bug will be less likely.
- Avoid code duplication between team members.
Conclusion
Surely after the article, you already know the Design Patterns you need to know in laravel, right. Understanding these Design Patterns helps a lot in the process of being a project with that Laravel Framework. We look forward to your suggestions