laravel最佳实践
着意闻时不肯香,香在无心处。
Single responsibility principle
A class and a method should have only one responsibility.
Bad:
1 | public function getFullNameAttribute() |
Good:
1 | public function getFullNameAttribute() |
Fat models, skinny controllers
Put all DB related logic into Eloquent models or into Repository classes if you’re using Query Builder or raw SQL queries.
Bad:
1 | public function index() |
Good:
1 | public function index() |
Validation
Move validation from controllers to Request classes.
Bad:
1 | public function store(Request $request) |
Good:
1 | public function store(PostRequest $request) |
Business logic should be in service class
A controller must have only one responsibility, so move business logic from controllers to service classes.
Bad:
1 | public function store(Request $request) |
Good:
1 | public function store(Request $request) |
Don’t repeat yourself (DRY)
Reuse code when you can. SRP is helping you to avoid duplication. Also, reuse Blade templates, use Eloquent scopes etc.
Bad:
1 | public function getActive() |
Good:
1 | public function scopeActive($q) |
Prefer to use Eloquent over using Query Builder and raw SQL queries. Prefer collections over arrays
Eloquent allows you to write readable and maintainable code. Also, Eloquent has great built-in tools like soft deletes, events, scopes etc.
Bad:
1 | SELECT * |
Good:
1 | Article::has('user.profile')->verified()->latest()->get(); |
Mass assignment
Bad:
1 | $article = new Article; |
Good:
1 | $category->article()->create($request->all()); |
Do not execute queries in Blade templates and use eager loading (N + 1 problem)
Bad (for 100 users, 101 DB queries will be executed):
1 | @foreach (User::all() as $user) |
Good (for 100 users, 2 DB queries will be executed):
1 | $users = User::with('profile')->get(); |
Comment your code, but prefer descriptive method and variable names over comments
Bad:
1 | if (count((array) $builder->getQuery()->joins) > 0) |
Better:
1 | // Determine if there are any joins. |
Good:
1 | if ($this->hasJoins()) |
Do not put JS and CSS in Blade templates and do not put any HTML in PHP classes
Bad:
1 | let article = `{{ json_encode($article) }}`; |
Better:
1 | <input id="article" type="hidden" value="{{ json_encode($article) }}"> |
Or
1 | <button class="js-fav-article" data-article="{{ json_encode($article) }}">{{ $article->name }}<button> |
In a Javascript file:
1 | let article = $('#article').val(); |
Use config and language files, constants instead of text in the code
Bad:
1 | public function isNormal() |
Good:
1 | public function isNormal() |
Use shorter and more readable syntax where possible
Bad:
1 | $request->session()->get('cart'); |
Good:
1 | session('cart'); |
Use IoC container or facades instead of new Class
new Class syntax creates tight coupling between classes and complicates testing. Use IoC container or facades instead.
Bad:
1 | $user = new User; |
Good:
1 | public function __construct(User $user) |
Do not get data from the .env file directly
Pass the data to config files instead and then use the config() helper function to use the data in an application.
Bad:
1 | $apiKey = env('API_KEY'); |
Good:
1 | // config/api.php |
Store dates in the standard format. Use accessors and mutators to modify date format
Bad:
1 | {{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }} |
Good:
1 | // Model |
Other good practices
Never put any logic in routes files.
Minimize usage of vanilla PHP in Blade templates.
https://github.com/alexeymezenin/laravel-best-practices
https://laravel-china.org/articles/12762/eighteen-best-practices-of-laravel