In the previous two chapters, you learned how to create your environment so that you can use Composer to install fresh Laravel applications, and you learned many more other nitty-gritty details of Laravel. You also are now familiar with the concepts of the Model-View-Controller (MVC) logic system.
In this chapter, you will learn how Laravel follows the MVC pattern.
To enter an application, you need to have an entry point. The basic algebraic definition of function works here: you give input to a function, and you get output. When applying this to Laravel, you can replace the word input with request and replace the word output with response.
To start creating a Laravel application, the web.php file in the routes directory is important. It takes the requests from you, the user, and sends them to either a closure that gives a response, a view page that displays the response, or a controller that does the same thing; in some critical cases, the controller consults with the model and then is updated by the business logic.
You will learn all about this mechanism in this chapter.
Route Definitions
In this example, the Laravel route accepts a URI through the HTTP GET method using a closure. The closure (also called an anonymous function) returns a view page. I will come back to that in a minute, but I need to point out one more thing here: the Route class uses a static method, which is a class-level method. Why does it not use an instance of Route? This is because a class-level variable consumes less memory than objects, whereas an object, once instantiated, starts consuming memory. This is an important concept of object-oriented programming.
This file defines the application’s URL endpoints so Laravel knows how to respond to that request. Here the URI is the document root or home page, and the Closure or anonymous function returns a view that contains an HTML page. These views are called view pages , and they are based on the Blade template engine that Laravel ships with.
This is a simple and expressive method of defining routes where models and controllers are absent. However, in a real-world scenario, you keep controllers between models and views, and the routes are initiated by the controllers. You will see an example of that in a few minutes.
In the previous code, inside the welcome controller’s index method, you can return the same view.
How to Find the Default Route Files
The Laravel framework automatically loads the route files in the routes directory. For the web interface, the routes/web.php file defines the routes. In Chapter 3, you will see how these routes are assigned to the web middleware group. Actually, route provides many features such as session state and CSRF protection. There is another middleware group, called api. I will also discuss this group later in this chapter.
In most cases, you will start by using this routes/web.php file . However, using closures is not a workable option. In some special cases, you will definitely use closures, but you will normally use a dedicated controller to manage a connected resource, as I showed in the previous code snippet.
Let’s think about a TaskController. This controller might retrieve all tasks. It gets all tasks views, inserts a new task, edits and updates an existing task, and finally deletes an existing list from the database.
Route and RESTful Controller
Since you will normally use a dedicated controller to manage a connected resource, the concept of RESTful or resourceful controllers applies here. In the “Resourceful Controller” section, I will discuss resourceful controllers in more detail, but before that, all you need to know is that a RESTful or resourceful controller can handle all seven routes associated with it. For now, you should know that when you use a create-read-update-delete (CRUD) approach, you use HTTP methods such as GET, POST, PUT, and DELETE. How do you get seven routes from this? Well, you use GET four times: to show all content, to show a form to create new content, to show a particular piece of content (ideally getting that by its ID), and finally to show the edit form to update the content.
Now, you can view all the tasks by typing http://example.com/tasks in your browser because the controller is waiting for the request and is programmed to display all the tasks.
What does the term RESTful mean? There is a fundamental difference between a web application and a REST API. When you get the response from a web application, it generally consists of HTML, CSS, and JavaScript. On the other hand, the REST API returns data in the form of JSON or XML. As you progress, you will learn more about the close relationship between Laravel and JSON output.
How to List All Routes
In a large application, it is quite cumbersome to maintain a list of all the routes. There might be hundreds of routes, and they are connected to dedicated resources with separate business logic.
Creating Controllers, Views, and Managing Routes
I have already pointed out why you need a controller. You cannot define all of your request handling logic as closures in route files. Instead, you can organize this action using controller classes. Controller class group related request handling logic into a single class. You can create a controller quite easily by keeping the connected resources in mind. Controllers can be stored in the app/Http/Controllers directory.
There are seven methods that you need to create a CRUD system for your connected resources. Here the connected resources are the Task model , through which you will handle your database and business logic. The other parts of resources are your related views page through which you will handle all types of front-end operations such as showing tasks and creating, editing, and deleting your tasks.
While creating the TaskController, I have added an extra parameter called --resource. Because of that parameter, I get all seven CRUD methods in my TaskController. I could have created them manually, but Laravel takes care of creating them automatically because I passed that parameter while creating the Controller class.
CRUD and the Seven Methods
The single line of code shown previously handles all seven methods created by default in the TaskController class.
If you issue the php artisan route:list command, you will see the related URIs, names, actions, and methods.
Let’s try to understand how it works. When you type a URI like http://example.com/tasks in your browser, The ‘task resource’ sends the GET requests. The index.blade.php page belonging to the resources/views/tasks folder displays all tasks.
The third method is a GET, and the URI is http://example.com/tasks/create . It will display a form in the create.blade.php page belonging to the resources/views/tasks folder. Here you will fill up all the related fields and hit the Submit button. Once you do that, the second method will start acting. That is the POST, and you do not need to have the store.blade.php file. Laravel handles this POST request automatically in the TaskController class.
And it goes on like this.
In the previous code, I skipped the destroy method, but it should give you an idea of how you can associate your controller class to a connected resource.
At the same time, you need to see the Task model and the database table that you have created so that this connection between the Model-Controller-View is complete.
Now, you have successfully created the model and created the migration.
For brevity, I have kept this model and the migration tasks table quite simple. So, to create a model and related database table, you need to issue the command php artisan make:model Task -m. Only after that are the model and the related database table created.
After running the previous command, you get a task table in the database/migration folder. Now you can add more functionality to that table by adding new columns. After the modification, you will issue another command so that Laravel knows that it should take the necessary steps to modify it.
Now, your route, model, controller, and view circle is complete. You will learn how each of these components works in later chapters. Understand that you should have the resources as separate as possible. They must be loosely coupled so that each controller has a connected model and view pages.
Models Acts as a Resource
Now through the Model class you can build bridges to the other parts of your application. But that is a different thing. I will discuss later how Eloquent relationships work and how each database table communicates with each other.
The TaskController class opens up its two methods (index and show) only for guests or the public. To operate other methods, you need to be an authenticated user, and then you can also apply authorization and all the other related middleware actions.
In the “Authentication, Authorization, and Middleware” Chapter 8, I will discuss the methodologies behind the TaskController class. Until then, know that through your Controller class you can control your entire application. The greatness of Laravel is that it also gives you ample chances to control your application through other parts, such as your route file, view page, and the model.
In the next section, you will see how resourceful controllers come to your rescue while you try to maintain a separation of concerns.
Now go to http://localhost:8000/tasks/3, which is the third task. In the TaskController class, the method is show.
I will discuss this part in a moment, so please keep reading.
Models Act As Resources
I would like to mention one thing: the TaskController class manages the task resource in such a way that you can view the index.blade.php and show.blade.php pages without being authenticated. However, you can do that in other parts of the same resource.
Why does this happen?
This clearly states that if the user is not admin , they cannot view this page. Otherwise, it redirects the user to the home page, which again redirects back to the login page.
I hope that you can now follow the logic behind Laravel’s routes, controller, model, and view mechanism. In the route lists, you can see how these components are related to each other. For each request, whether that be GET or POST, Laravel handles it nicely and relates it to the respective URI. Then that URI fires up the respective RESTful Controller method, and that takes you to the respective view page.
In the next section, you will see how the RESTful or resourceful controller encapsulates those URI requests in a single line.
Resourceful Controllers
With a single line of code, how can you handle a typical CRUD route to a controller? Laravel’s resource routing is the answer. You want to store every task in your database. You want to edit and update every task. You want to create a controller that handles all HTTP requests for tasks stored by your application.
Now, this single route declaration creates multiple routes to handle a variety of actions on the resource. If you open the app/HTTP/Controllers/TaskController.php file, you will find that each of these actions has related notes informing you of the HTTP verbs and URIs they handle.
This clearly states “Display a listing of the resource.” At the same time, if you watch the route listing (shown next), you will find for the action AppHttpControllersTaskController@index that the name is tasks.index (this means the index.blade.php file belonging to the tasks folder). The method is GET, and the URI is tasks. This means if you type the URI http://localhost:8000/tasks, you will view all the tasks.
The Importance of the Resourceful Controller
Creating controllers in Laravel is simple. In an MVC pattern, controllers play a vital role, and defining all your request handling logic as an anonymous function in a route file is not a viable solution for a big application. So, you will always use controllers as a transport medium. The main advantage of a controller is that it can group all the request handling into a single class, and that class can be stored in the app/HTTP/Controllers directory .
A resourceful controller uses many types of HTTP verbs at the same time, such as GET, POST, PUT/PATCH, and DELETE. By using the GET verb, you can access four action methods in the controller; they are index, create, show, and edit. The action methods in the controller handle the route names of the same name; for example, the index action would handle a URI like /myfiles and a route name of myfiles.index. The create and edit actions only show web forms, so the GET verb is perfect for them.
You need a POST verb or method for the store action because you are sending data to the app, and behind the scenes, the Laravel service container (I will discuss this later in detail) takes the trouble to go through the model to insert new data in the related database table. The URI remains the same as index, like /myfiles, but the action method changes to store, and the route name also changes to myfiles.store. The HTTP verb PUT/PATCH is used for updating only a single record. Therefore, the URI changes to /myfiles/{myfile}, the action method changes to update, and the Route name changes to myfiles.update.
How to Supplement the Resource Controller
However, you should keep your controller focused, and to do that, my suggestion is that it is better to maintain several small controllers so you don’t have to juggle with the position in your route file.
Getting User Input and Dependency Injection
The Laravel service container is used to resolve all Laravel controllers. This means that when you create a resource controller, method injection normally occurs. How does this work?
Here, you may ask, how does Laravel know the wildcard reference or input variable $id along with the Request $request object? This happens through the Reflection class that Laravel uses to guess what you are type hinting, and this is called method injection .
Basically, you could have passed the parameter’s Model object as ' instead of $id; however, since through the edit form you have passed $id, Laravel resolves the dependencies and injects it into the controller instance in place of '.
The position of the $id along with the Request $request object is interchangeable. Laravel is smart enough to read the wildcard entry and the $request object here. So, you can type hint the dependencies on your controller methods. The most common use case is the injection of the IlluminateHttpRequest instance.
The instance of DBUserRepository always provides better testability.
How a Blade Template Works with Controllers and Models
Blade is a simple yet powerful template engine. It reduces the workload of the front-end staff drastically. With Blade templates, you can also use PHP code. Besides, it has its own PHP syntax, which is extremely easy to use.
The advantage of Blade views is that they come with automatic caching. All Blade view pages are compiled into plain PHP code and cached until you modify them. This means zero overhead for the application.
You can create any Blade view page with a .blade.php extension, and they should be stored inside the resources/views folder. For a large application, you may create separate folders for each resource and keep your view pages inside that. Likewise, I have kept my Task resource view pages inside the resources/views/tasks folder.
Two basic benefits of Blade are template inheritance and sections.
As you see, you can easily connect your view page to the master layout page by writing the following on the top of the page: @extends('layouts.app'). In between @section('content') and @endsection, you insert the content part. Basically, you are following the DOM object model for displaying the HTML page. It starts on the top and flows down to the end.
But I have overwritten the default app.blade.php page to make it simple to understand. When Laravel installs, it comes with a default app.blade.php view page in the resources/views/layouts folder.
The @section and @yield directives are there with the typical HTML markup. The @section directive defines a section of content. Here, the @yield directive is used to display the contents of a given section.
Security in Blade
In any Blade view page, you usually get the data inside curly braces: {{ $data->body }}'. These statements are automatically sent through PHP’s htmlspecialchars function to avoid XSS attacks so that the data is escaped.
If you do not want to escape data, then use this syntax: {!! $data->body !!}. But, be careful about the user’s input. It is always a good practice to escape data supplied by users. The user’s input data should be displayed using double curly braces: {{ $user->data }}'.
Authentication Through Blade
Control Structures in Blade
Other Advantages of Blade Templates
In this case, when the loop finds that the ID is 1, it continues. After that, when the code reaches the second user, the loop stops and spits out the first two users’ names, and after that it stops and breaks out from the loop when it finds the third user.
You can manipulate your database records by managing the control structures in the Blade view pages. And in such cases, Laravel allows you to do that without touching the models and controllers. This is a big advantage of using Laravel.