devnotes.

Writing Controllers

Controllers group related request-handling logic into a single class, instead of defining every action as a closure in your routes file. Generate one with:

php artisan make:controller PostController
namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\View\View;

class PostController extends Controller
{
    public function index(): View
    {
        $posts = Post::latest()->paginate(10);
        return view('posts.index', compact('posts'));
    }

    public function show(Post $post): View
    {
        return view('posts.show', compact('post'));
    }
}

A resource controller (php artisan make:controller PostController --resource) scaffolds all seven standard CRUD methods (index, create, store, show, edit, update, destroy) automatically, pairing naturally with Route::resource().

For actions that don't fit the CRUD mold, single-action controllers are handy — a class with just one __invoke() method, registered as Route::post('/subscribe', SubscribeController::class);. Laravel 13's new PHP attribute support also lets you configure controllers and requests with attributes rather than base-class properties in some cases, reducing boilerplate further.

Laravel Controllers Tutorial | DevNotes