Getting Started with Controllers in Laravel

Vitaliy Dotsenko
Legacybeta
Published in
5 min readApr 15, 2020
Getting Started with Controllers

In the previous article we reviewed basic routing in Laravel and how to use them with Closure or with the controller’s action. You can always just use a Closure, however if you’re dealing with a small application or you don’t need to have route caching to improve routing performance — then it’s better to use Controllers instead. Usually, the controller contains different actions with the code in which the incoming requests are processed and return a response to the user.

To generate a new controller in Laravel you can use artisan command:

php artisan make:controller SomeController

This command creates a new file in app/Controllers/SomeController.php with the SomeController class which extends the standard Laravel Controller class.

The new generated file will be:

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class SomeController extends Controller
{
//
}

Also, you can generate a single action controller by the command:

php artisan make:controller SomeController --invokable

It means the controller can handle only one action in the method __invoke() which will be called by the router, you can put your code in this method.

The new controller file will be:

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class SomeController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
//
}
}

To register the route for the above controller you should specify the controller name without the action name like:

Route::post('/some-address', 'SomeController');

Then Laravel router automatically will call the __invoke() method and put the object of the Request as a parameter. This object contains the values from the incoming HTTP request, you have access to them using the method input() with passing the parameter name into it:

$request->input('some_param');

The input() method returns values from request’s including query string values.

Sometimes it’s good to have predefined values as a default value if the parameter won’t be passed. Because by default if the parameter isn’t passed this method returns NULL value. To change the default value we need to pass the second argument to the input() method:

$request->input('some_param', 'some_default_value');

If you need to get all incoming parameters you can call the method all() without any arguments:

$allParams = $request->all();

or call the method input() without any arguments:

$allParams = $request->input();

Artisan has the argument ーresource to easily create a new controller to process basic CRUD actions:

php artisan make:controller SomeController --resource

This command creates the file SomeController.php with the content:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SomeController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}

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

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}

/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}

/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}

/**
* Update the specified resource in storage.
*
* @param
\Illuminate\Http\Request $request
* @param
int $id
* @return
\Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

Then you can define the routes for the above controller in the router file just using the method resource():

Route::resource('/some-address', 'SomeController');

The actions have predefined names:

  • index() — to get the list of the entities. GET request and match to URI /some-address.
  • create() — show the HTML form to create a new entity. GET request and match to URI /some-address/create.
  • store() — use the fields from the HTML form and create a new entity. POST request and match to URI /some-address, additionally required CSRF token.
  • show() — show the entity, uses id to identify the entity. GET request and match to URI /some-address/{id}.
  • edit() — show the update form, gets the existing entity’s values by entity id. GET request and match to URI /some-address/{id}/edit.
  • update() — use the fields from the form and update the existing entity by the entity id. PUT or PATCH request and match to URI /some-address/{id}, additionally required CSRF token.
  • destroy() — delete the entity by the entity id. DELETE request and match to URI /some-address/{id}, additionally required CSRF token.

The methods POST, PUT, PATCH and DELETE require additional CSRF token field. The hidden input field _token can be added by detective @csrf in the Blade templates. Or if you use AJAX — using the HTTP request header X-CSRF-TOKEN. It needs to prevent Cross-Site Request Forgery (CSRF) attacks, when an attacker doing a web request (send HTML form) without the user’s permission, for example, send the HTML form to the payment system to create an illegal payment. If you need to disable CSRF protection in the Laravel you should add URIs into the $except array to the file app/Http/Middleware/VerifyCsrfToken.php.

The HTML forms support only GET or POST methods, in Laravel other HTTP methods can be used by the Blade directive @method():

<form action="/some-address" method="POST">
@method('PUT')
</form>

For checking your API methods you can use one of the popular HTTP clients:

  • Postman- downloadable app, good for checking localhost;
  • Postwoman- open source, works in the browser, but not easy to check localhost;
  • HTTPie — open source, a good tool if you like the console.

Usually, for the REST API you don’t need to have create() and edit() actions and related routes because they display HTML form and it’s not necessary for REST. In Laravel you can generate controller without that actions just add --api to artisan command:

php artisan make:controller SomeController --api

and exclude create and edit routes, call the apiResource() method instead of the resource():

Route::apiResource('/some-address', 'SomeController');

This was a general review of Laravel controllers, you can read more about them in the official Laravel documentation.

--

--

Vitaliy Dotsenko
Legacybeta

I like coding, open-source software and hi-tech 🚀