Stick to PSR & Laravel Conventions
Consistency is key. Follow PSR-12 and Laravel’s own standards. Use PSR-4 autoloading, consistent naming, and avoid creative shortcuts.
// Good
public function getUserProfile(int $id): User
{
return User::findOrFail($id);
}
// Bad
public function get_user_profile($ID)
{
return User::find($ID);
}
Use laravel/pint
or php-cs-fixer
to auto-format code.
Master Eloquent Relationships
Don’t manually query related data when you can define relationships using Eloquent’s powerful API.
// Post.php
public function comments()
{
return $this->hasMany(Comment::class);
}
// Usage
$comments = $post->comments;
Use Route Model Binding
Don’t write unnecessary lookup logic. Let Laravel inject models automatically.
// web.php
Route::get('/users/{user}', [UserController::class, 'show']);
// UserController
public function show(User $user)
{
return view('users.show', compact('user'));
}
Avoid User::findOrFail($id)
when you can use route model binding.
Move validation logic to its own class for readability and reusability.
// StorePostRequest.php
public function rules()
{
return [
'title' => 'required|string|max:255',
'body' => 'required|min:10',
];
}
// Controller
public function store(StorePostRequest $request)
{
Post::create($request->validated());
}
Keep Controllers Thin
Controllers should delegate logic, not contain it.
// Bad
public function store(Request $request)
{
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
$user->save();
}
// Good
public function store(StoreUserRequest $request)
{
UserService::create($request->validated());
}
Leverage Collections & Helpers
Collections simplify data transformations and logic.
$active = User::all()->filter(fn($u) => $u->is_active);
// Eloquent equivalent
$active = User::where('is_active', true)->get();
// Useful helpers
optional($user)->profile;
Str::slug($title);
Keep Blade Templates Clean
Prepare data in your controller instead of doing logic in Blade.
// Controller
$isAdmin = $user->is_admin && $user->created_at->diffInDays(now()) > 30;
return view('dashboard', compact('isAdmin'));
// Blade
@if($isAdmin)
<p>Welcome, experienced admin!</p>
@endif
Name Things Clearly
Use expressive variable and method names. Your future self and teammates will thank you.
// Clear
$totalInvoiceAmount = $invoices->sum('amount');
// Vague
$t = $invoices->sum('amount');
Write Tests—Even Small Ones
Testing isn’t just for big teams. Write small, focused tests to catch regressions.
public function test_user_can_login()
{
$user = User::factory()->create();
$this->post('/login', [
'email' => $user->email,
'password' => 'password',
])->assertRedirect('/dashboard');
}
Refactor Ruthlessly
Revisit and simplify code regularly. Break large methods into smaller ones. Extract logic into services or traits.
Clean code is a continuous journey — refactoring is your compass.