Laravel Beauty: Recipes & Best Practices
https://viblo.asia/p/laravel-beauty-recipes-best-practices-6BAMYk9Evnjz
Last updated
https://viblo.asia/p/laravel-beauty-recipes-best-practices-6BAMYk9Evnjz
Last updated
Đọc thêm: https://vinasupport.com/huong-dan-cai-dat-laravel-ide-helper/
Tự động tạo PHPDoc cho Laravel Facades
Tự động tạo PHPDocs cho models
Tạo PHPDocs cho các phương thức Laravel Fluent
Auto-completion cho factory builders
PhpStorm Meta cho Container instances
Chạy lệnh sau để Laravel IDE Helper update các Facades
Để update các Models
Laravel là một Open-source PHP Web Application Framework, được tạo ra bởi Taylor Otwell. Mặc dù ra đời khá là muộn màng khi mới chỉ bắt đầu từ năm 2011, tuy nhiên cho đến nay thì Laravel đã trở thành PHP Framework phổ biến nhất (và tuyệt vời nhất, theo quan điểm của mình =))). Cộng đồng Laravel rất active, số lượng package cho Laravel cũng cực kỳ nhiều và phong phú. Laravel bỏ xa hoàn toàn các framework khác về số lượng stars hay số lượng forks trên Github!
Một trong những điểm mình yêu thích nữa ở Laravel đó là nó thật sự là một Modern Full Stack Framework, giúp cho việc phát triển web trở nên cực kỳ nhanh chóng và đơn giản. Để thực hiện việc đó thì Laravel mang trong mình rất nhiều rất nhiều những tư tưởng mới mẻ, với những khái niệm hay Design Pattern thú vị.
Mình cũng rất thích điểm Laravel thường xuyên yêu cầu phiên bản PHP rất cao, như từ bản 4.2 đã yêu cầu PHP 5.4 trở lên, hay phiên bản 5.1 ra mắt tháng 6 vừa qua đã yêu cầu PHP từ 5.5.9 (trong khi có những framework PHP khác giờ vẫn còn dậm chân support PHP 5.3 (facepalm)). Việc yêu cầu những phiên bản PHP cao như vậy giúp cho người lập trình viên dễ dàng tiếp cận với "phong cách" code hiện đại, và với những tính năng mới hơn.
Mội vài package bạn nên có trong mỗi Project của mình.
Laravel Debugbar sẽ giúp bạn theo giõi hoạt động của project của mình được tốt hơn. Như việc có những request nào, đi qua những route nào, sử dụng những view nào, hay thực hiện những câu truy vấn SQL nào ... Việc kiểm tra được số lượng cũng như nội dung các câu truy vấn SQL sẽ giúp bạn biết lúc nào code của mình hoạt động tốt, lúc nào cần phải tối ưu code.
Thế nên Laravel Debugbar thực sự là một công cụ không thể thiếu giúp cho việc phát triển với Laravel trở nên dễ dàng hơn.
Nếu bạn đang sử dụng những IDE trong việc phát triển với Laravel thì Laravel IDE Helper sẽ là một công cụ rất hữu ích dành cho bạn.
Laravel IDE Helper đem lại khả năng Auto Complete cho rất nhiều class của Laravel, đặc biệt trong đó có Facade (thứ mà không một IDE nào hiểu được là nó hoạt động như thế nào =))).
Ngoài ra Laravel IDE Helper còn có khả năng auto comment cho Model theo chuẩn của PHPDoc. Nếu project của bạn yêu cầu phải viết comment đầy đủ và chặt chẽ, thì hãy để Laravel IDE Helper giúp đỡ một phần nào cho bạn.
N + 1
và Eager LoadingHãy giả sử bạn gặp một vấn đề như thế này:
Bạn có một danh sách các bài viết trong bảng posts
, với Model Eloquent tên là Post
Mỗi Post thuộc về một User. Post có quan hệ belongsTo
với User, và User có quan hệ hasMany
với Post.
Bạn có một trang Post list, cần hiển thị ra một danh sách các Post, dĩ nhiên với tên tác giả của post đó. Đây là một tình huống rất hay thường gặp trong các project, với nhiều biến thể khác nhau. Và dưới đây là một cách giải quyết thường gặp.
Như vậy để in ra tên của chủ nhân của bài viết, ta đã sử dụng đến quan hệ user
mà mình đã định nghĩa, tức nó sẽ lấy ra User chủ nhân của bài Post. Nếu bạn cài Laravel Debugbar thì bạn sẽ nhận ra những vấn đề của phương pháp này:
Với mỗi một bài Post ta phải thực hiện một câu truy vấn SQL để lấy ra User. Nếu số lượng bài post của bạn là lớn thì số lượng câu truy vấn SQL phải thực cũng sẽ là lớn.
Có khả năng bị thực hiện những câu truy vấn trùng lặp nhau. Chẳng hạn bài post số 1, 2, 3 đều thuộc user có id là 1. Trong trường hợp đó ta sẽ phải thực hiện 3 câu truy vấn SQL cùng với mục đích là lấy ra user có id bằng 1 (để gán vào cho từng bài post).
Nên biết truy vấn SQL thường là một trong những tác vụ tốn nhiều thời gian nhất trong một xử lý request. Rõ ràng việc phải sử dụng nhiều câu truy vấn như vậy là một vấn đề ta cần khắc phục. Ta gọi vấn đề đó là N + 1 problem
, bởi ngoài việc dùng 1 câu truy vấn để select ra N bài post, bạn sẽ phải sử dụng tiếp N câu truy vấn để lấy ra N user cho N bài post đó.
Laravel cung cấp một công cụ để giải quyết vấn đề này, đó là Eager Loading.
Với việc sử dụng hàm with()
hay load()
, ta có thể load một lúc ra tất cả các User thuộc về tất cả các Post chỉ bằng một câu truy vấn SQL. Điều này sẽ giúp ta giảm số lượng câu truy vấn đi một cách đáng kể.
Hãy luôn cố gắng dùng Eager Loading những lúc có thể nhé. Laravel cung cấp cho chúng ta một hệ thống Eager Loading rất hoàn hảo và mạnh mẽ. Bên cạnh việc load một quan hệ như trên, ta còn có thể load một lúc nhiều quan hệ (Multiple Relationships Eager Loading), load quan hệ chồng nhau (Nested Eager Loading), hay thực hiện Eager Loading có kèm điều kiện ...
Thông tin chi tiết về cách sử dụng Eager Loading các bạn có thể xem tại Official Document của Laravel
Tiếp tục một vấn đề liên quan đến quan hệ của Eloquent. Giả sử như bạn gặp một vấn đề như sau:
Mỗi Category có nhiều Post. Mỗi Post thuộc về một Category.
Bạn có một trang Category view, và trong trang hiện thông tin chi tiết về category đó thì bạn cần hiện ra số lượng bài viết có trong category. Để giải quyết được vấn đề lấy số lượng bài post trong một category ta có cách như sau.
Như mình viết ở trên thì ta có 2 cách viết là $category->posts->count();
và $category->posts()->count();
. Bạn có biết nó khác nhau thế nào không ?
Đầu tiên ta cần biết rằng $category->posts()
là lời gọi hàm posts()
từ instance $category
, trong khi đó posts
là lời gọi property.
Cách gọi $category->posts()
thì như định nghĩa ở trên là return $this->hasMany(Post::class);
, ta có thể thấy nó sẽ trả về instance của Category. Tuy nhiên trong Model Category không hề có property nào là posts
cả, vậy cách gọi $category->posts
sẽ trả về cái gì ?
Câu trả lời là Laravel sử dụng các Magic Method của PHP để biến việc gọi property posts
trở nên hợp lệ. Và nó sẽ trả về kết quả của quan hệ posts
. Tức $category->posts
ở đây sẽ tương đương với $category->posts()->get()
. Một điều đặc biệt của phép gọi qua property là Laravel sẽ chỉ query DB ở lần đầu tiên, nhận về kết quả và sẽ lưu kết quả đó vào property mới tạo ra.
Ở trên ta có Category quan hệ hasMany
với Post, do đó $category->posts
sẽ trả về một Collection (Collection
là một Class trong Laravel giúp quản lý Array được dễ dàng và thuận tiện hơn).
Như vậy ta có thể thấy cách làm việc của 2 câu lệnh nêu trên sẽ là như sau:
$category->posts->count()
: Đầu tiên $category->posts
sẽ query DB để lấy ra tất cả các posts thuộc về category hiện tại. Kết quả là một Collection. Sau đó hàm count()
được gọi trên Collection này để đếm số lượng phần tử của Collection. Nó đơn giản cũng giống như hàm count()
đếm số lượng phần tử của mảng vậy. Tức với câu lệnh này ta sẽ lấy hết posts thuộc về category trong DB ra, và dùng xử lý PHP để đếm số lượng posts đó. Bạn gọi câu lệnh này bao nhiêu lần đi chăng nữa thì cũng chỉ có một lần duy nhất câu query DB được thực hiện, đó là ở lần gọi đầu tiên.
$category->posts()->count()
: Đầu tiền $category->posts()
sẽ trả về instance $category
với điều kiện query là quan hệ posts
. Sau đó hàm count()
được sử dụng là hàm của Eloquent, với nhiệm vụ build ra câu query count
trong MySql chẳng hạn. Tức với câu lệnh này, ta sẽ chạy duy nhất một câu query DB là đếm số lượng bản ghi posts thuộc về category. Mỗi lần gọi câu lệnh này là một lần bạn phải query DB.
Khi đã hiểu được bản chất của 2 cách gọi kia thì bạn sẽ có thể tự xem xét xem mình nên sử dụng cách viết nào trong trường hợp nào. Chẳng hạn như bạn có một trang Category view, ở đó chỉ cần hiện ra số lượng bài viết trong Category mà không cần quan tâm đến nội dung các bài post thì rõ ràng cách gọi $category->posts()->count()
là tối ưu hơn nhiều. Tuy nhiên nếu cần phải in ra cả các bài posts nữa thì cách gọi $category->posts->count()
lại tốt hơn, bởi vì dù gì thì bạn cũng cần gọi $category->posts
để lấy ra các bài posts, sau đó gọi thêm hàm count
từ đó sẽ giúp bạn không cần phải query thêm DB một lần nữa.
Dependency Injection là một design pattern được sử dụng phổ biến trong các Framework hiện đại. Hiểu đơn giản có nghĩa là nếu một Class A hoạt động phụ thuộc vào một vài Class khác, thì thay vì khởi tạo các instance của các Class kia bên trong Class A, ta sẽ inject những instance đó vào thông qua constructor
hay setter
. Những instance của các Class mà Class A cần để hoạt động đó được gọi là dependency.
Trong khuôn khổ của bài viết này mình sẽ không đi sâu phân tích vào khái niệm Dependency Injection, đây là một khái niệm quan trọng các bạn nên tìm hiểu và nắm vững. Thay vào đó, ta hãy cùng xem qua một cách sử dụng Dependency Injection hiệu quả trong Laravel nhé.
Laravel cung cấp cho chúng ta một công cụ cực mạnh tên là Service Container. Đó là nơi quản lý Class Dependency, tức xem một Class có những Class phụ thuộc nào. Ngoài ra nó cũng giúp chúng ta thực hiện Dependency Injection một cách hiệu quả thông qua class constructor. Service Container của Laravel có thể giúp bạn inject dependency vào rất nhiều loại Class, từ Controller, Event listeners, cho đến Queue Jobs, Middleware, Console Command ...
Chẳng hạn như ta có thể inject class Mailer
vào bên trong Controller như sau (ví dụ thôi nhé, còn bạn không nên thực hiện logic gửi mail bên trong Controller làm gì =)))
Đơn giản như vậy đó, bạn không cần phải biết cách khởi tạo một instance Mailer như thế nào, nó cần những dependencies gì. Bạn chỉ việc type-hint tên class hay interface, và Service Container
làm hết cho bạn phần còn lại.
Thậm chí bên trong Controller bạn còn có thể inject được vào bên trong từng method như sau:
Đương nhiên ở trên chỉ là một ví dụ về Dependency Injection trong Laravel, để tiếp cận với request
, bạn có thể có nhiều cách khác nhau:
Có thể trong các bài viết sau này, mình sẽ đi sâu vào phân tích bản chất của các hàm helper cũng như cách hoạt động của Facade, khi đó thì các bạn sẽ hiểu rõ hơn 3 cách gọi ở trên về bản chất là có gì khác nhau hay không?
Repository Design Pattern hiện là một phương pháp làm việc với project Laravel rất phổ biến. Hiểu một cách đơn giản đó là bạn sẽ tạo ra một tầng Repository ở giữa Controller và Model (ORM Layer), với nhiệm vụ là thực hiện các business logic xử lý DB, từ đó tránh được việc viết Business Logic ở cả Controller lẫn Model, tạo ra những hàm có thể được sử dụng lại ở nhiều nơi khác nhau.
Với Repository Pattern, Controller sẽ không còn làm việc trực tiếp với Model nữa, nó cần xử lý liên quan đến DB, nó sẽ làm việc với Repository.
Các bạn có thể tìm hiểu thêm về Repository Design Pattern thông qua mốt số bài viết sau:
Ngoài ra bạn có thể implement Repository Pattern trong project Laravel của mình một cách dễ dàng với package Laravel 5 Repositories
Một ví dụ nhỏ, sử dụng Repository Pattern, kết hợp với Dependency Injection.
Trên đây mình đã giới thiệu một số vấn đề đơn giản mà mình hay gặp phải trong công việc cùng những cách giải quyết mình hay sử dụng.
Hy vọng nó sẽ giúp ích được ít nhiều cho các bạn.
Từ phần tiếp theo của loạt bài viết này, mình sẽ tập trung đào sâu về những phần core của Laravel, những Design Pattern được implement bên trong Laravel, cách thức hoạt động cũng như cách sử dụng những khái niệm rất mới mẻ nhưng thú vị như Inversion Of Control, Service Provider, Contract, Facade, Middleware, Job, Event ...
All rights reserved
MỤC LỤC
BÀI VIẾT THUỘC SERIES
Laravel: The Beauty1. 2. 3. 4. 5.
CÁC TỔ CHỨC ĐƯỢC ĐỀ XUẤT
Làm thế nào để đếm quan hệ trong Eloquent một cách hiệu quả?Ho Quoc Hai1 phút đọc 569 0 33Laravel Beauty: Tìm hiểu về Service containerTran Duc Thang15 phút đọc 27710 85 41161Tối ưu lại code Laravel của chính mìnhQuiet8 phút đọc 12133 66 2655Laravel Beauty: Tìm hiểu về FacadeTran Duc Thang12 phút đọc 18799 50 2177Laravel Beauty: Tìm hiểu về Service ProviderTran Duc Thang15 phút đọc 26386 44 2497Laravel Beauty: Tìm hiểu về ContractTran Duc Thang8 phút đọc 8274 23 1043Tìm hiểu về Repository Pattern trong Laravel ( Part II )Dung Nguyen Quang9 phút đọc 8800 10 320Một vòng laravel (Part 4)Nguyễn Phúc Lương9 phút đọc 773 3 07Laravel: Eloquent relationshipsNguyen Van Giang3 phút đọc 1358 1 03Làm thế nào để đếm quan hệ trong Eloquent một cách hiệu quả?Ho Quoc Hai1 phút đọc 569 0 33Laravel Beauty: Tìm hiểu về Service containerTran Duc Thang15 phút đọc 27710 85 41161Tối ưu lại code Laravel của chính mìnhQuiet8 phút đọc 12133 66 2655Laravel Beauty: Tìm hiểu về FacadeTran Duc Thang12 phút đọc 18799 50 2177Laravel Beauty: Tìm hiểu về Service ProviderTran Duc Thang15 phút đọc 26386 44 2497
Một số Design Principles trong lập trình mà bạn nên biếtTran Duc Thang22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy StandardTran Duc Thang19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong BlockchainTran Duc Thang19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management SystemTran Duc Thang14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershipTran Duc Thang30 phút đọc 401 4 015[Become A SuperUser] Find system filesTran Duc Thang9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & SolutionsTran Duc Thang16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)Tran Duc Thang18 phút đọc 3110 10 019Tìm hiểu về giải thuật Đệ QuyTran Duc Thang22 phút đọc 8558 6 018Cùng ôn lại các khái niệm về Cấu trúc dữ liệu, Giải thuật, Độ phức tạp thuật toán.Tran Duc Thang19 phút đọc 3221 34 158Simple Rules to make your code Cleaner (Part 2)Tran Duc Thang22 phút đọc 862 4 212Simple Rules to make your code Cleaner (Part 1)Tran Duc Thang15 phút đọc 1133 9 019Một số Design Principles trong lập trình mà bạn nên biếtTran Duc Thang22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy StandardTran Duc Thang19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong BlockchainTran Duc Thang19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management SystemTran Duc Thang14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershipTran Duc Thang30 phút đọc 401 4 015[Become A SuperUser] Find system filesTran Duc Thang9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & SolutionsTran Duc Thang16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)Tran Duc Thang18 phút đọc 3110 10 019
E làm với Laravel đc khá nhiều rồi nhưng sao càng đọc càng k hiểu nhỉ...hihi, đúng là phải hiểu thì mới thấy nó cao siêu thế nào
@chithanh1012 Ừ, cái hay của Laravel là càng tìm hiểu thì mình lại càng thấy những hiểu biết của mình về nó càng ít ỏi =)) Nhưng mà càng tìm hiểu thì lại càng thấy nó tuyệt vời!
Bài viết hay và dễ hiểu. E thích cách anh viết ở chỗ : // View. We can use $category->posts->count(); // Or $category->posts()->count();
Đến cuối cùng có kết luận cho hai cách gọi này. Tks Thắng ạ.
Mình thấy phần Before start nên giới thiệu thêm về chuẩn PSR, có thể sử dụng php-cs-fixer (https://github.com/FriendsOfPHP/PHP-CS-Fixer) để tự động format code theo PSR.
Quá bá! (baiphuc)
thank Bác, đã biết được nhiều thêm thông tin của laravel.
thanks anh a. bai viet rat hay
good job
đỉnh qá
Tks anh, bài viết hay nhất trên viblo mà em từng đọc!!
Trong loạt bài viết Laravel Beauty này, mình sẽ cố gắng gửi đến các bạn những hiểu biết của mình về những điều tuyệt vời của Laravel, hay những kinh nghiệm hữu ích khi làm việc với một project Laravel. Hy vọng các bạn có thể thêm hiểu và thêm yêu thích Framework tuyệt vời này
Và cũng do tích chất có phần hơi lý thuyết của những bài viết như vậy thế nên nếu bạn là một người mới bắt đầu học Laravel, chưa từng làm một project nào về Laravel thì bạn nên xem qua về Document của Laravel trước. Nó thật sự là khá đầy đủ và hữu ích đấy
Ngoài ra bạn cũng nên sử dụng thêm một công cụ là Laravel Log Viewer, để có thể dễ dàng check nội dung từ những file logs
mà Laravel sinh ra bên trong thư mục storage/logs
từ trang web của mình. Nên chú ý là đừng có để quyền truy cập vào trang view logs đó cho tất cả mọi users nhé
Cả ba cách thức trên sẽ đều trả ra kết quả giống nhau mà thôi, và sử dụng cách thức nào thì có thể là do các thành viên trong team quyết định
Happy Coding with Laravel!
Sun* R&D Product Development 2 39 68 2.1KSun* Cebu Branch / Awesome Ars Academia Cebu 14 21 60 19.1KRoot Of Genius 18 3 17 41.5K
Đăng nhập để bình luậnDream @chithanh1012thg 1 3, 2016 12:07 CH
0 |Trả lờiChia sẻTran Duc Thang @thangtd90thg 1 4, 2016 10:17 SA
0 |Trả lờiChia sẻdecodedmrq @decodedmrqthg 1 29, 2016 2:37 CH
0 |Trả lờiChia sẻTri Ha @trihtmthg 7 9, 2016 2:22 CH
0 |Trả lờiChia sẻNgo Duy Son @ngo.duy.sonthg 7 23, 2016 1:33 CH
0 |Trả lờiChia sẻNguyễn Đức Trung @ductrung081thg 5 25, 2017 4:46 CH
0 |Trả lờiChia sẻDai Nguyen @daint6997thg 5 12, 2018 10:22 CH
0 |Trả lờiChia sẻDat Dao @datagitthg 1 24, 2019 1:55 CH
0 |Trả lờiChia sẻDương Quang Mạnh @D.Manhthg 8 25, 2020 1:49 CH
A ơi sửa lại link đi ạ, những link đầu bài đều không vào được
+1 |Trả lờiChia sẻTran Duc Thang @thangtd90thg 8 25, 2020 2:26 CH
do URL Viblo thay đổi cấu trúc :v
Anh update lại rồi
+1 |Trả lờiChia sẻTrần Phát @Mr.Simplethg 1 27, 2021 5:29 CH
Bạn nghĩ laravel là tảng băng trôi? Không nó là đại dương.
0 |Trả lờiChia sẻVu Phong @phongltktvthg 7 4, 2021 5:23 CH
0 |Trả lờiChia sẻThiên Ngô @phantomkid2thg 3 14, 1:50 CH