More Tutorials on Web Development
Table of Contents
Introducing the MVC Structure
The MVC structure means that the application is divided into three parts. The (M) model defines the data model, (V) view presents data and (C) controller defines logic and manipulates data.

Controllers
Here is a link to the controller section of the official documentation: https://laravel.com/docs/8.x/controllers
Basic Controllers
A controller is a place where you organize the behaviours of your app. For example, when the router receives “/
“, it returns a “IndexController
“.
The “IndexController
” retrieves required information from the database, and then put them in the corresponding location of a view, and finally returns the view to the browser.
This is the most basic use of a controller. Of course, it can do a lot more than that, and I will talk about them as we encounter specific problems later in the tutorial.
To create our first controller. Go to the terminal, type in:
php artisan make:controller IndexController
Go to app/Http/Controllers/
, and you will find a IndexController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class IndexController extends Controller
{
//
}
Note that the controller extends the base controller class included with Laravel. The base class provides a few convenience methods such as the middleware
method.
We can try to make it return a string by creating a function inside the class:
class IndexController extends Controller
{
//
public function index()
{
return 'this is a controller';
}
}
We created a method called index()
, and inside the method, it returns a string 'this is a controller'
.
In order to test our code, we need to make a router return the “IndexController
“. Go back to web.php
, and create a new router like this:
use App\Http\Controllers\IndexController;
Route::get('/', [IndexController::class, 'index']);
Notice the second argument is no longer a function, it is [IndexController::class, 'index']
, which means go to the IndexController
, find the index()
method, and execute whatever is in it.
In the browser, go to http://localhost/

We can also make the IndexController
to return a view.
class IndexController extends Controller
{
//
public function index()
{
return view('welcome');
}
}
Refresh the browser, this will get us the same result as we did in the previous article:

Single Action Controllers
Single action controllers are useful when we only need one method in the controller class:
class IndexController extends Controller
{
//
public function __invoke()
{
return view('welcome');
}
}
Now we can change the route we just defined. We no longer need to specify the method.
Route::get('/', IndexController::class);
This code will work exactly the same as before.

Views (Blade Templates)
Let’s reexamine the view welcome.blade.php
, you will notice it is just an HTML file. Yes, views are based on HTML and CSS since they are what you see in the browser, but things are slightly more complicated than that.
If it contains only HTML codes, the entire blog would be static, and that is not what we want. So the view would have to “tell” the controller where to put the data it retrieved.
Template Inheritance
Define A Master Layout
The primary benefit of using the Blade template is that we do not need to write the same code over and over again. Let’s create a master.blade.php
file in the templates folder.
<html>
<head>
@yield('meta')
</head>
<body>
@section('sidebar')
<div class="container">
@yield('content')
</div>
</body>
</html>
Notice the two directives @section
and @yield
. The @section('sidebar')
means Laravel will look for a blade template named “sidebar.blade.php
“, and import it here. The @yield
directive is used to display the contents of a given section.
Extend A Layout
Here, we create another view index.blade.php
.
@extends('master')
@section('meta')
<meta charset="UTF-8">
<meta name="description" content="Free Web tutorials">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="author" content="John Doe">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
When this view is called, Laravel will look for the master
blade template we just created. Replace @yield('meta')
with the meta
section, and replace @yield('content')
with the content section.
With these two directives, we are able to build any type of template hierarchy we want.
Syntax
Displaying Data
Let’s first make some changes to our IndexController:
class IndexController extends Controller
{
//
public function __invoke()
{
return view('index', ['name' => 'Eric']);
}
}
we defined a variable name
here, and its value is Eric
. Remember, this is also the new syntax in Laravel 8.
In the index view, we change the content section into this:
<p>Hello, {{ $name }}.</p>
The output will be Hello, Eric.
.
If Statements
You may construct if
statements using the @if
, @elseif
, @else
, and @endif
directives. These directives function identically to their PHP counterparts:
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
Switch Statements
Switch statements can be constructed using the @switch
, @case
, @break
, @default
and @endswitch
directives:
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
Loops
In addition to conditional statements, Blade provides simple directives for working with PHP’s loop structures. Again, each of these directives functions identically to their PHP counterparts:
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
@while (true)
<p>I'm looping forever.</p>
@endwhile
Models
Remember I said controllers are in charge of retrieving data from the database? Well, that’s where models come in.
Each database table has a corresponding “Model”, and that model will handle all the interactions with the table.
Define Models
The easiest way to create a model instance is using the make:model
Artisan command:
php artisan make:model Test
If you want to generate the corresponding migration files, you may use the --migration
or -m
option:
php artisan make:model Test --migration
php artisan make:model Test -m
Here is an example of a model and migration file:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
//
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTestsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tests', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tests');
}
}
We won’t go into details about these right now since it can be quite confusing for beginners. Instead, we’ll talk about them with real examples later in the tutorial.
Retrieve Data
Laravel has an elegant way of retrieving data, with Eloquent. Think of each Eloquent model as a powerful query builder allowing you to fluently query the database table associated with the model.
$flights = App\Models\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get();
Again, we’ll go into details about this later.
I’m very thankful to you because your knowledge got me a job… Thanks again, mate.
Best method of organizing lessons I’ve ever seen for Laravel.
Many thanks.
So far, this is a very good tutorial. Thank you. Definitely going to bookmark this!
Hello.
About: “Let’s first make some changes to our IndexController:”
Than you change to: public function __invoke()
This returns error: Method App\Http\Controllers\IndexController::index does not exist.
Did you meant: public function index()
?
Thank you.
Hello Miroslav,
The
public function __invoke()
means this is a single action controller, and the corresponding route should beRoute::get('/', IndexController::class);
I mentioned this part here: https://www.techjblog.com/index.php/2020/09/laravel-tutorial-3-the-mvc-structure/#Single_Action_Controllers
You can choose to use a regular controller if you want, but you must change the corresponding router.
Hey Eric. Thanks for the tutorial. You had missed adding the IndexController to the web.php route.
use AppHttpControllersIndexController;
You are right. Thank for the reminder.
But.. where is the Templates directory?!
If you are using PyCharm, the “templates” directory should be automatically created for you. If not, you can still create your own, but you have to specify the path in the settings.py file.