Laravel Controllers
Laravel controllers group request-handling logic into classes instead of putting everything in route closures. Controllers live in app/Http/Controllers and keep your routes file short and readable.
Creating a Controller
php artisan make:controller PageControllerINFO Controller [app/Http/Controllers/PageController.php] created successfully.
A Basic Controller
Each public method is an action. Point a route to it with an array of the class and method name.
<?php
namespace App\Http\Controllers;
class PageController extends Controller
{
public function home()
{
return view('home', ['title' => 'Welcome']);
}
public function pricing()
{
$plans = ['Basic' => 9, 'Pro' => 29];
return view('pricing', compact('plans'));
}
}
// routes/web.php
Route::get('/', [PageController::class, 'home']);
Route::get('/pricing', [PageController::class, 'pricing']);GET / -> renders resources/views/home.blade.php GET /pricing -> renders resources/views/pricing.blade.php
Laravel Resource Controllers
A resource controller comes with index, create, store, show, edit, update and destroy methods, matching Route::resource. Add --model to get route model binding in the signatures.
php artisan make:controller PostController --resource --model=PostINFO Controller [app/Http/Controllers/PostController.php] created successfully.
A CRUD Controller Example
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return view('posts.index', ['posts' => Post::latest()->paginate(10)]);
}
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|max:200',
'body' => 'required',
]);
$post = $request->user()->posts()->create($data);
return redirect()->route('posts.show', $post)->with('status', 'Post created!');
}
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
public function destroy(Post $post)
{
$post->delete();
return to_route('posts.index');
}
}POST /posts -> validates, saves, redirects to /posts/1 with flash "Post created!"
Single-Action Controllers and Dependency Injection
A controller with one __invoke method handles a single route. Laravel automatically injects any type-hinted class into constructors and methods via the service container.
<?php
namespace App\Http\Controllers;
use App\Services\ReportService;
class DownloadReportController extends Controller
{
public function __invoke(ReportService $reports)
{
return response()->download($reports->monthlyCsvPath());
}
}
// Route::get('/reports/download', DownloadReportController::class);GET /reports/download -> downloads report-2026-10.csv
Frequently asked questions
What is a resource controller in Laravel?
A controller containing the seven standard CRUD actions (index, create, store, show, edit, update, destroy) that pair with Route::resource.
Should business logic go in controllers?
Keep controllers thin. Put validation in form requests and complex logic in service or action classes so it can be reused and tested.
What is an invokable controller?
A controller with a single __invoke method. You register it by passing just the class name to the route.