Controllers
Controllers group related request-handling logic into a class.
Syntax
class PostController extends Controller { ... }Instead of writing all your logic in route closures, you can organize it into controller classes stored in app/Http/Controllers. Each public method handles a route.
Generate one with php artisan make:controller PostController.
Example
namespace App\Http\Controllers;
class PostController extends Controller
{
public function index()
{
$posts = Post::all();
return view('posts.index', ['posts' => $posts]);
}
}When to use it
- A developer moves an anonymous route closure that was growing long into a dedicated controller class so the logic can be unit-tested and reused.
- A team adopts single-action controllers (one __invoke method per class) for complex one-off endpoints like /checkout/confirm to keep each class focused.
- An admin panel registers all CRUD operations for the User model with a single Route::resource() line pointing at a UserController.
More examples
Generate and register a controller
Artisan scaffolds the controller file in app/Http/Controllers/; the --resource flag pre-fills all seven CRUD method stubs.
php artisan make:controller ProductController
# Or generate a full resource controller
php artisan make:controller ProductController --resourceA minimal controller method
Shows a controller extending the base Controller class, fetching paginated products, and returning a Blade view.
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\View\View;
class ProductController extends Controller
{
public function index(): View
{
$products = Product::latest()->paginate(20);
return view('products.index', compact('products'));
}
}Single-action controller
A single-action controller defines only __invoke(), so the class itself is passed directly to the route without specifying a method name.
// app/Http/Controllers/ProcessCheckoutController.php
class ProcessCheckoutController extends Controller
{
public function __invoke(Request $request): RedirectResponse
{
// handle checkout logic
return redirect()->route('orders.confirmation');
}
}
// routes/web.php
Route::post('/checkout', ProcessCheckoutController::class);
Discussion