How to create controllers in Laravel: A practical guide

Updated: January 15, 2024 By: Guest Contributor Post a comment

Introduction

Laravel, a widely-used PHP framework, simplifies the process of web application development. Among the numerous features it provides, controllers are a fundamental part of its MVC (Model-View-Controller) architecture. In this guide, we will delve into creating controllers in Laravel, assisting developers to efficiently manage their application’s logic.

Getting Started with Controllers

Controllers group related request handling logic within a single class. To begin, ensure you have Laravel installed and a project set up. Use the following command to create your first controller.

php artisan make:controller MyFirstController

This command creates a new controller named ‘MyFirstController’ inside the ‘app/Http/Controllers’ directory. Let’s start with a simple method within this controller:

public function show()
{
    return 'Hello, World!';
}

An associated route in ‘routes/web.php’ is needed to access this method using a web browser:

Route::get('/greet', 'MyFirstController@show');

When you visit http://{your-domain.com}/greet, you’ll see the text ‘Hello, World!’ displayed.

Passing Data to Views

Typically, controllers pass data to views. Here’s an example controller method that retrieves data from a model and passes it to a view:

public function index()
{
    $items = Item::all();
    return view('items.index', compact('items'));
}

The associated view file ‘resources/views/items/index.blade.php’ might look like this:

<ul>
    @foreach ($items as $item)
        <li>{{ $item->name }}</li>
    @endforeach
</ul>

Our ‘index’ route in ‘routes/web.php’ specifies the URL path to use this controller action:

Route::get('/items', 'ItemController@index');

Visiting http://{your-domain.com}/items displays a list of items.

Resource Controllers

Laravel allows for automatic creation of CRUD (Create, Read, Update, Delete) methods within a controller using the resource controller generator:

php artisan make:controller ItemController --resource

This will scaffold all the necessary methods. You can quickly define routes to these controllers:

Route::resource('items', 'ItemController');

These routes adhere to RESTful conventions and simplify the usual CRUD operations.

Middleware and Controllers

Middleware can be used to filter HTTP requests entering your application. Controllers can specify middleware like this:

public function __construct()
{
    $this->middleware('auth');
}

This will ensure that all routes within the controller are only accessible to authenticated users. Specific methods can also be targeted:

$this->middleware('log')->only('index');

$this->middleware('subscribed')->except('store');

Dependency Injection and Controllers

Laravel supports dependency injection for resolving services out of the service container. Within a controller, you might inject a service like so:

use App\Services\PaymentService;

public function __construct(PaymentService $paymentService)
{
    $this->paymentService = $paymentService;
}

You can now use $this->paymentService within your methods to access its functionality.

Advanced Controller Techniques

As applications grow, you may need more advanced controller features. Laravel provides facilities to handle these requirements:

Implicit Model Binding

Laravel can automatically inject model instances into your routes. For instance:

public function show(Item $item)
{
    return view('items.show', compact('item'));
}

In your route definition:

Route::get('items/{item}', 'ItemController@show');

Laravel will retrieve the Item instance that corresponds to the ID in the URL.

Single Action Controllers

When a controller handles a single action, you may use the ‘__invoke’ method:

php artisan make:controller ShowProfile --invokable

In this controller, define a single method:

public function __invoke($id)
{
    // ...
}

Bind it to a route as follows:

Route::get('user/{id}', 'ShowProfile');

Testing Controllers

It’s important to test controllers to ensure they behave as expected. Laravel simplifies this with testing methods. Here’s an example of a feature test that verifies a user can view items:

public function testUserCanViewItems()
{
    $response = $this->get('/items');
    $response->assertStatus(200);
    $response->assertSee('Item Name');
}

Conclusion

Laravel controllers are powerful tools for organizing the logic of web applications. By following best practices, separating concerns, and making use of Laravel’s features, you can build maintainable and testable controllers. Embrace the art of controlling your app logic with finesse and precision.