Working With Controllers and Middleware in Laravel 5.5

In the previous installment in the series on Laravel 5.5 series, I discussed the concept of routing and its implementation in Laravel 5.5. In this tutorial, I will discuss the C of MVC architecture – Controllers in Laravel. I will highlight the various types of controllers and the idea of Middlewares in Laravel 5.5.

In Laravel 5.5, all controllers are created in the Controllers folder, located in App/Http/Controllers. All the controllers must have namespace App\Http\Controllers and extends from the Controller class.

Create a Basic Controller

Remember the tables example in the article on routing.

I will now create a controller with a single method which will print the required table on the screen. To define a controller in Laravel, first give it a name. In this example, I will name the controller Table and then add Controller to the name. The full name of the controller class is now TableController. Remember that all the controllers in Laravel must have the word Controller at the end.

You can create controllers in two ways:

Manually create a file

Use Artisan to create the controller (this is the easy option!)

I will now demonstrate how you could create a controller using the Laravel Artisan command. I will use the following command for creating the controller using Artisan:

1

php artisan make:controller TableController

Once the command is completed, an empty TableController class will be generated in the Controllers folder with name TableController.php. At this point, the class looks like:

1

2

3

4

5

6

7

8

9

10

11

12

13

<?php

namespaceApp\Http\Controllers;

useIlluminate\Http\Request;

classTableControllerextendsController

{

//

}

I will now add the logic for generating the table. Create a new method create inside TableController:

1

2

3

4

5

6

publicfunctioncreate($number=2)

{

for($i=1;$i<=10;$i++){

echo"$i * $number = ".$i*$number."<br>";

}

}

This is the same logic that I used in the rout (refer to the article on Laravel routes). I will now remove this functionality from the route and then bind the controller to it

Now whenever the URL is executed, the control action create will be called and the table for the number would be generated.

Create a Resource Controller

Resource controllers are used to create CRUD options for routes.

Let’s say, I have a model for Books and now I want to create a controller for it which will perform its CRUD methods for the route in the controller. Laravel provides an easy way of doing this. Using a single command, I can create a resource controller and define a Model with it (another great feature of Laravel 5.5).

I will use the following command for creating a resource controller:

1

php artisan make:controller BookController--resource

Once the command is executed, you will be asked to create the Book model since it does not exists at the moment. Type yes for now and hit Enter. Once it finishes, a BookController will be created along with the model binded in it. You will get the following actions in the BookController:

index() → To view all Book lists

create() → To load a view to create a new book

store(Request $request) → To save the newly created book

show($id) → To view a single book

edit($id) → To load a view for editing

update(Request $request, $id) → To update a single book

destroy($id) → To delete a book

The best part is that you do not need to define all the CRUD routes individually in the web.php file.Just define the resource route for the controller in web.php file:

1

Route::resource('book','BookController');

This single declaration will create several routes to handle BooksController requests. The resource route will handle the following actions:

VerbURIActionRoute Name

GET

/books

index

books.index

GET

/books/create

create

books.create

POST

/books

store

books.store

GET

/books/{book}

show

books.show

GET

/books/{book}/edit

edit

books.edit

PUT/PATCH

/books/{book}

update

books.update

DELETE

/books/{book}

destroy

books.destroy

You can also specify a resource route to handle only certain actions or can exclude the actions that you do not want a route to handle. Here is the syntax of the code snippets for both the situations:.

1

2

3

4

5

6

7

8

9

10

11

Route::resource('book','BookController',['only'=>[

'index','show'

]]);

Route::resource('book','BookController',['except'=>[

'create','store','update','destroy'

]]);

Once you save the file, only the following routes will be handled:

Controller-Model Binding in Laravel 5.5

With Laravel 5.5, you can now bind a model(s) to your resource controller by adding --model=modelname to the Artisan command.

1

php artisan make:controller BookController--resource--model=Book

When you run this command, the following functions will be binded to controllers.

show(Book $book) → view a single book

edit(Book $book) → load a view for editing

update(Request $request, Book $book) → update a single book

destroy(Book $book) → delete a book

Model binding is important because it reduces the lines of code and streamline the overall design of the application. Take the example of getting a book by its id. When not using model binding, I would require the following steps to find the book details through the id.

PHP

1

2

3

4

5

publicfunctionshow($id)

{

$book=Book::where('id',$id)->get();

returnview('book.book',['book’=>$book]);

}

Now, with model binding, I only have to return the view of that Book and all the rest, i.e. finding the book by the id and error generation will be done by Laravel itself.

PHP

1

2

3

4

publicfunctionshow(Book$book)

{

returnview('book.book',['book'=>$book]);

}

As you could see in this example, I have managed to reduce one line of code. In larger projects, this advantage would become more apparent!.

This is it for controllers. You can learn more about resource routing in Laravel in the official documentation. I will now discuss Middlewares in Laravel.

What Are Middleware and Where to Create Them?

Middleware are the easiest way of verifying HTTP requests before they are passed to the controller. All middleware in Laravel are created in the Middleware folder, located inside the app/HTTP folder.

Creating a Basic Middleware in Laravel 5.5

The process of creating a middleware is very similar in both Laravel 5.3 and Laravel 5.5.

I will now create a middleware for our Books controller in which the books that correspond to a particular year will not be stored in the database. I will name this middleware CheckYear and use the following Artisan command:

Shell

1

php artisan make:middleware CheckYear

Once the command is finished a middleware will be create with a handle function (to which I will add the logic).

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<?php

namespaceApp\Http\Middleware;

useClosure;

classCheckYear

{

/**

* Handle an incoming request.

*

* @param \Illuminate\Http\Request $request

* @param \Closure $next

* @return mixed

*/

publicfunctionhandle($request,Closure$next)

{

$year=['1956','1970','1972'];

if(array_has($year,$request->year)){

returnredirect('home');

}

return$next($request);

}

}

In the above code, I defined the array $year, in which I added the years which I do not want to add into the database. Next, I used the Laravel helpers function array_has to check the input for year coming from the request. If the year is exists in the array, it will be redirected to home. Otherwise, the request will be completed.

Now that I have a middleware, I will now define a controller. The easiest way to define the middleware is in the constructor of the controller. Remember to define the namespace of the middleware in the controller as well. See the following code for defining the middleware in the constructor:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<?php

namespaceApp\Http\Controllers;

useApp\Book;

useIlluminate\Http\Request;

useApp\Http\Middleware\CheckYear;

classBookControllerextendsController

{

/**

* Constructor.

*

* @return void

*/

publicfunction__construct()

{

$this->middleware(CheckYear::class);

}

You can define the middleware in app/Http/Kernel.php file, in $routemiddleware array and assign a key to it. Check out the following code:

Create a Middleware for Controller Without a Separate Class

In a controller, you can define a middleware without writing a separate class for it. The code for the middleware and the constructor is:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

<?php

namespaceApp\Http\Controllers;

useApp\Book;

useIlluminate\Http\Request;

classBookControllerextendsController

{

/**

* Constructor.

*

* @return void

*/

publicfunction__construct()

{

$this->middleware(function($request,$next)

{

$year=['1956','1970','1972'];

if(array_has($year,$request->year)){

returnredirect('home');

}

return$next($request);

});

}

This will work as if you have created a separate class for the middleware. Check out the official documentation for more information on middlewares. That’s it now it works as same as you have created a separate class for it. You can learn more about middleware in Laravel 5.5 from the official documentation.

Conclusion

In this tutorial, I offered an overview of controllers and middleware in Laravel 5.5. I discussed how to create simple and resource controllers and how to define their routes. I also discussed how to create simple middlewares and how to bind them to controller and routes. If you wish to add a suggestion or have a question, do leave a comment below
want to add anything in it feel free to comment below.

Create Laravel apps without the worry of server management.

About Ahmed Khan

Ahmed was a PHP community expert at Cloudways – A Managed PHP Hosting Cloud Platform. He is a software engineer with extensive knowledge in PHP and SEO. He loves watching Game of Thrones is his free time. Follow Ahmed on Twitter to stay updated with his works. You can email him at ahmed.khan@cloudways.com