All about Controllers in Laravel 10

What are Controller?

In Laravel, Controllers are PHP classes that handle incoming HTTP requests and manage the application's response to those requests. They act as an intermediary between the Model (data) and the View (UI) in the MVC (Model-View-Controller) pattern. Controllers contain methods that define the actions that can be taken on a resource, such as creating, reading, updating, and deleting data. They allow developers to organize and modularize their code by separating the application's logic into smaller, more manageable pieces. By using controllers, developers can easily add new features and modify existing functionality in their applications.

How to create Controller?

We can create a controller in Laravel using the make:controller Artisan command.

php artisan make:controller CategoryController

This will create a CategoryController class inside the app/Http/Controllers directory. By default, the controller will have an empty index method, which you can modify to define the logic for handling requests to the route that is associated with this controller.

We can also use the --resource option to generate a controller that includes the common RESTful methods (index, create, store, show, edit, update, destroy) for a given model:

php artisan make:controller CategoryController --resource

This will create a new file called CategoryController.php in the "app/Http/Controllers" directory with boilerplate code for a resource controller.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Category;

class CategoryController extends Controller
{
    public function index()
    {
        $categories = Category::all();
        return view('categories.index', compact('categories'));
    }

    public function create()
    {
        return view('categories.create');
    }

    public function store(Request $request)
    {
        $category = new Category();
        $category->name = $request->input('name');
        $category->save();

        return redirect()->route('categories.index');
    }

    public function show($id)
    {
        $category = Category::find($id);
        return view('categories.show', compact('category'));
    }

    public function edit($id)
    {
        $category = Category::find($id);
        return view('categories.edit', compact('category'));
    }

    public function update(Request $request, $id)
    {
        $category = Category::find($id);
        $category->name = $request->input('name');
        $category->save();

        return redirect()->route('categories.index');
    }

    public function destroy($id)
    {
        $category = Category::find($id);
        $category->delete();

        return redirect()->route('categories.index');
    }
}
HTTP VerbActionRouteController Method
GETIndex/resourceindex()
GETCreate/resource/createcreate()
POSTStore/resourcestore()
GETShow/resource/{id}show()
GETEdit/resource/{id}/editedit()
PUT/PATCHUpdate/resource/{id}update()
DELETEDestroy/resource/{id}destroy()

What are Single Action Controller?

Single Action Controllers are a feature of Laravel that allow developers to create controllers that contain a single method to handle a specific HTTP request. Instead of defining all the methods that would be used for RESTful CRUD operations, single action controllers are used to define a single method to handle a specific action.

For example, a single action controller could be used to handle a form submission or to perform a search query. This can help keep code organized and reduce the number of controller files needed for a project.

Single action controllers can be created using the __invoke magic method or by defining a method with a unique name and registering it as a route using the Route::get() or Route::post() methods.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    public function __invoke()
    {
        return view('home');
    }
}

In this example, the HomeController class has a __invoke method that returns a view named home. This controller can be used to handle requests that only require rendering the home view.

Single Action Controllers are used when we have a controller that only needs to handle a single action. It helps to simplify our code and makes it easier to read and maintain. Instead of having a controller with multiple actions, we create a separate controller for each action.

For example, if we have a contact form that only needs to handle the submit action, we can create a single action controller called ContactController with the __invoke method handling the form submission. This makes it easier to manage the code for that specific action and ensures that the controller only handles what it needs to.

How to assign Middleware to Controllers?

Yes, we can assign middleware to controllers in Laravel. Middleware can be assigned globally to all routes, to specific routes or to specific controller methods.

To assign middleware to a specific controller, we can use the $middleware property in the controller class. For example:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class MyController extends Controller
{
    /**
     * The middleware the should be applied to methods in this controller.
     *
     * @var array
     */
    protected $middleware = [
        'auth',
        'verified',
    ];
    
    // Controller methods here
}

In the above example, the auth and verified middleware will be applied to all methods in the MyController controller class.

Resource Controller

In Laravel, a resource controller is a controller that provides a set of methods for handling HTTP requests related to a resource, such as creating, reading, updating, and deleting it.

By defining a resource controller, you can easily handle CRUD (Create, Read, Update, Delete) operations for a resource without having to manually create each method in the controller. Laravel provides an artisan command make:controller with --resource option to generate a resource controller.

The resource controller has the following methods:

  • index() - display a listing of the resource
  • create() - show the form for creating a new resource
  • store(Request $request) - store a newly created resource in storage
  • show($id) - display the specified resource
  • edit($id) - show the form for editing the specified resource
  • update(Request $request, $id) - update the specified resource in storage
  • destroy($id) - remove the specified resource from storage

Each method in the resource controller corresponds to a particular HTTP request method and URI. For example, the index() method handles GET requests to the resource's index URI, while the store(Request $request) method handles POST requests to the resource's store URI.

When you define a resource controller, Laravel automatically creates several methods to handle common RESTful actions for the resource, such as index, create, store, show, edit, update, and destroy. These methods correspond to the HTTP verbs GET, POST, PUT/PATCH, and DELETE.

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $post = new Post;
        $post->title = $request->input('title');
        $post->content = $request->input('content');
        $post->save();

        return redirect()->route('posts.index');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $post = Post::find($id);
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $post = Post::find($id);
        return view('posts.edit', compact('post'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $post = Post::find($id);
        $post->title = $request->input('title');
        $post->content = $request->input('content');
        $post->save();

        return redirect()->route('posts.show', $post->id);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $post = Post::find($id);
        $post->delete();

        return redirect()->route('posts.index');
    }
}

To register a resource controller in your application, you can use the Route::resource method in your routes/web.php file:

Route::resource('posts', App\Http\Controllers\PostController::class);

To create it

php artisan make:controller PostController --resource
HTTP VerbURIAction
GET/your-resourcePostController@index
GET/your-resource/createPostController@create
POST/your-resourcePostController@store
GET/your-resource/{id}PostController@show
GET/your-resource/{id}/editPostController@edit
PUT/PATCH/your-resource/{id}PostController@update
DELETE/your-resource/{id}PostController@destroy

Thats all about Controller. We'll discuss more about it in our next posts.