Kritim Yantra
Mar 16, 2025
Laravel controllers are the backbone of your application's HTTP layer, acting as intermediaries between routes and your business logic. In this guide, we’ll explore Laravel 12 controllers in depth, complete with practical examples and best practices.
Instead of writing all your route logic in routes/web.php
, controllers help keep your code clean, separate concerns effectively, and enable the reuse of common functionality—all while following RESTful conventions.
Controllers organize your application's request-handling logic using PHP classes. They allow you to group related request logic into a single class, making your application easier to maintain and more scalable.
Use Artisan to create a controller:
composer artisan make:controller PostController
This creates app/Http/Controllers/PostController.php
:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
// Controller methods go here
}
Let's add some simple methods:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return view('posts.index');
}
public function show($id)
{
$post = Post::findOrFail($id);
return view('posts.show', compact('post'));
}
}
In routes/web.php
, connect your controller to routes:
<?php
use App\Http\Controllers\PostController;
// Individual routes
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{id}', [PostController::class, 'show']);
// Resource route (creates multiple routes)
Route::resource('posts', PostController::class);
Generate a resource controller with:
php artisan make:controller PostController --resource
This creates methods for standard RESTful actions:
HTTP Method | URI | Action | Route Name |
---|---|---|---|
GET | /posts | index | posts.index |
GET | /posts/create | create | posts.create |
POST | /posts | store | posts.store |
GET | /posts/{post} | show | posts.show |
GET | /posts/{post}/edit | edit | posts.edit |
PUT/PATCH | /posts/{post} | update | posts.update |
DELETE | /posts/{post} | destroy | posts.destroy |
For APIs (excluding create/edit views), you can generate an API resource controller:
php artisan make:controller API/PostController --api
Example API controller:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return Post::all();
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'content' => 'required'
]);
$post = Post::create($validated);
return response()->json($post, 201);
}
}
Laravel 12 automatically resolves dependencies through the service container. For example, injecting a service:
<?php
public function store(Request $request, PostService $postService)
{
$post = $postService->createPost($request->validated());
return redirect()->route('posts.show', $post);
}
Create dedicated request classes for validation:
php artisan make:request StorePostRequest
In app/Http/Requests/StorePostRequest.php
:
<?php
public function rules()
{
return [
'title' => 'required|max:255',
'content' => 'required|min:100',
'published_at' => 'nullable|date'
];
}
Then use it in your controller:
<?php
public function store(StorePostRequest $request)
{
$validated = $request->validated();
Post::create($validated);
return redirect()->route('posts.index');
}
Transform your data using API resources:
php artisan make:resource PostResource
In your controller:
<?php
public function show(Post $post)
{
return new PostResource($post);
}
public function index()
{
return PostResource::collection(Post::paginate(20));
}
Single-action controllers can be created with:
php artisan make:controller PublishPostController --invokable
Example implementation:
<?php
class PublishPostController extends Controller
{
public function __invoke(Post $post)
{
$post->publish();
return redirect()->route('posts.show', $post);
}
}
Route:
Route::post('/posts/{post}/publish', PublishPostController::class);
For related resources, use nested controllers. For example:
Route::resource('posts.comments', CommentController::class);
In your controller:
<?php
public function store(Post $post, Request $request)
{
$comment = $post->comments()->create($request->validated());
return redirect()->route('posts.show', $post);
}
Laravel controllers are powerful tools for organizing your application's logic. By following best practices—keeping controllers lean, using resourceful controllers, and leveraging features like dependency injection and route model binding—you can build robust and maintainable applications.
Whether you're building a simple blog or a complex RESTful API, these patterns and techniques help improve development speed, code clarity, and collaboration across your team.
Happy coding!
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google