Laravel is a web application framework that uses MVC (Model View Controller) design pattern.
It provides an easy way to craft web apps without worrying about a lot of stuff involved in web development.
Topics Covered:
Laravel Installation via composer:
composer create-project laravel/laravel laravel9app
You need to know Laravel 9.x requires a minimum PHP version of 8.0.
- Routing:
EX:
Basic Laravel Route
Route::get('/', function () {
return 'Hello World';
});
Route::get('/greeting', function () { //greeting is an endpoint
return 'Hello World';
});
Route::get('/', function () { //going back to normal
return view ('welcome');
});
Route with a Controller
php artisan make:controller UserController
UserControllerClass:
public function index() {
return view ("user");
}
Make a view:resources/views/user.blade.php
web.php:
Import the controller App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
or you can this one below works the same..
Route::get('/user', 'App\Http\Controllers\UserController@index');
Route with Parameter
public function show($id) {
return 'user Id:'. $id;
}
web.php
Route::get('/user/{id}', 'App\Http\Controllers\UserController@show');
Named Routes
You can have named routes like this,
Route::get('/user/profile', 'App\Http\Controllers\UserController@index')->name('profile');
Access the URL like this, http://127.0.0.1:8000/user/profile you get the same results.
Route Controller
If a group of routes all utilize the same controller, you may use the controller method to define the common controller for all of the routes within the group. This is introduced in laravel 9.
Import the controller class use App\Http\Controllers\UserController;
Route::controller(UserController::class)->group(function () {
Route::get('/user/profile', 'index');
Route::get('/user/{id}', 'show');
Route::post('/users', 'store');
});
If you run the php artisan route:list you can inspect the routes.
- Middleware:
Middleware provides a convenient mechanism for inspecting and filtering HTTP requests entering your application.
Middleware provides a way for a user to be authenticated in your application.
Authenticating particular routes:
Custom Middleware:
middleware can be used in three ways global, group and route level
php artisan make:middleware EnsureTokenIsValid
kernel.php:
register the middleware under the protected $routeMiddleware
'EnsureTokenIsValid' => \App\Http\Middleware\EnsureTokenIsValid::class,
EnsureTokenIsValid.php
Give the logic…
public function handle(Request $request, Closure $next)
{
if ($request->input('token') !== 'my-secret-token') {
return redirect('noaccess');
}
return $next($request);
}
}
Make a blade noaccess.blade.php
<title>Middleware</title>
</head>
<body>
<h1>You are not authorized!</h1>
</body>
</html>
web.php
Route::controller(UserController::class)->group(function () {
Route::get('/user/profile','index')->middleware(EnsureTokenIsValid::class);
Route::get('/noaccess', 'noaccess');
Route::get('/user/{id}', 'show');
Route::post('/users', 'store');
});
UserController.php
public function noaccess() {
return view ("noaccess");
}
access the Url: http://127.0.0.1:8000/user/profile?token=my-secret-token or..
Normal Url: http://127.0.0.1:8000/user/profile (redirected to noaccess page)
run php artisan route:list to inspect the routes created…
- CSRF Protection:
stands for cross-site request forgery whereby unauthorized commands are performed on behalf of an authenticated user.
The malicious user only needs to lure an unsuspecting user of your application to visit their website and their email
address will be changed in your application.
How it works:
A token will be generated this token is used to verify that the authenticated user is
the person actually making the requests to the application.
The App\Http\Middleware\VerifyCsrfToken middleware, which is included in the web middleware group by default,
will automatically verify that the token in the request input matches the token stored in the session.
Ex:
web.php
Route::controller(UserController::class)->group(function () {
Route::get('/user/profile','index');
Route::post('user/profile', 'post');
});
UserController.php
class UserController extends Controller
{
public function index() {
return view ("user");
}
public function post(Request $req) {
return $req->input();
}
}
User.blade.php
<section>
<form action ="" method="POST">
@csrf
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" name="submit" value="Submit">
</form>
</section>
run (php artisan route:clear) in case of the error POST method is not supported…
output:
{"_token":"LmdXT6OqYhQfciwyGZK1Xsc8gSVFun6uRFpK3gAi","username":"brian","password":"admin","submit":"Submit"}
Remember this token is unique and should match the token stored in the session.
- Controllers:
By default, controllers are stored in the app/Http/Controllers directory.
You can have a controller dedicated to a specific page ex UserController.php for users
So far we have defined a basic controller at the start of the tutorial now let’s look at
resource and middleware controllers
a) Resource Controllers:
To create a resource controller start by running this command
php artisan make:controller PostsController --resource
The controller will contain a method for each of the available resource operations. Then register a resource route that points to the controller:
Ex:
use App\Http\Controllers\PostsController;
Route::resource('posts', PostsController::class);
Remember you can run this command php artisan route:list to have a quick overview of the application routes.
You can have many resource controllers at once in an array in resources like this
Ex:
Route::resources([
'pages' => PagesController::class,
'posts' => PostsController::class,
]);
b) Controller Middleware
In Controller middleware, you can have something like this,
Ex:
Route::controller(UserController::class)->group(function () {
Route::get('/user/profile','index')->middleware('auth');
});
This means that the route /user/profile will be authenticated with a login page before you are allowed to see the contents of the page. Remember this will affect the particular route you have placed the middleware auth.
To apply the middleware auth in all your routes within your controller you will need to create a constructor and place it in your controller like this.
Ex:
class UserController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}
If you access any route defined in your controller you will be presented with a login page.
- Requests:
We have used requests already in our application.
public function post(Request $req) {
return $req->input(); // $req->all(),
}
We can query any particular value from our form, for example,
return $req->input('username'); // Brian
return $req->input('password'); // password
or you can have the method $req->all() which does the same function as $req->input() returns all the values.
- Responses
All routes and controllers should return a response to be sent back to the user’s browser.
The most basic is returning a string from a route Ex:
Route::get('/greeting', function () {
return "Hello World";
});
i) Responses Array
Here you may return an array Ex:
public function index() {
return [1, 2, 3];
}
ii) Return redirect
This is simply redirecting a user to another Url
Route::get('/greeting', function () {
return "Hello World";
//return redirect('user/profile');
});
iv) Return redirect back with input returns with input values in a form.
public function post(Request $req) {
// return $req->input();
return back()->withInput();
}
What method does it redirect us back with the same input instead of submitting the data? What it does is validates the request if the data submitted is invalid from the form will redirect us back.
v) Redirecting To Named Routes
to generate a RedirectResponse to a named route, you may use the route method:
Ex:
Route::get('/greeting', function () {
return redirect()->route('myprofile');
});
Route::get('/user/profile','index')->name('myprofile'); //named route
vi) Redirecting With Flashed Session Data
Ex:
Route::get('/greeting', function () {
return redirect('user/profile')->with('status', 'Welcome to laravel!');
});
user.blade.php
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
- Blade Templates
Blade templates can use plain PHP code and are compiled into plain PHP code and cached until they are modified.
Blade template files use the .blade.php file extension and are typically stored in the resources/views directory.
Ex:
go to resources/views/layouts/app.blade.php or you can use touch command
touch resources/views/layouts/app.blade.php copy and paste the code below into the app.blade.php
app.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
@include('inc.navbar')
<div class="container">
@yield('content')
</div>
</body>
</html>
Since you can see an inc.navbar you may be wondering, make a folder inc in resources/views/inc/navbar.blade.php or
touch resources/views/inc/navbar.blade.php and copy and paste the code below
<nav class="navbar navbar-expand-lg navbar-dark ftco_navbar bg-dark ftco-navbar-light" id="ftco-navbar">
<div class="container">
<a class="navbar-brand" href="#"></i> <span>Big</span> <span>Store</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#ftco-nav" aria-controls="ftco-nav" aria-expanded="false" aria-label="Toggle navigation">
<span class="oi oi-menu"></span> Menu
</button>
<div class="collapse navbar-collapse" id="ftco-nav">
<ul class="navbar-nav ml-auto">
<li class="nav-item active"><a href="/" class="nav-link">Home</a></li>
<li class="nav-item"><a href="/about" class="nav-link">About</a></li>
<li class="nav-item"><a href="/events" class="nav-link">Services</a></li>
<li class="nav-item"><a href="/sermons" class="nav-link">Shop</a></li>
<li class="nav-item"><a href="/blog" class="nav-link">Blog</a></li>
<li class="nav-item"><a href="/contact" class="nav-link">Contact</a></li>
</ul>
</div>
</div>
</nav>
this code gives us a bootstrap navbar to work with, remember in the app.blade.php we have imported the bootstrap cdn url to
give us bootstrap classes and so forth…
Now in the user.blade.php we need to make changes such as below
user.blade.php
@extends('layouts.app')
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
@section('content')
<h1>Hi user</h1>
<section>
<form action ="" method="post">
@csrf
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" name="submit" value="Submit">
</form>
</section>
@endsection
The layout.app extends the app.blade.php which has the navbar and yields the content that is presented in our app. Then we
have the starting and ending section which typically defines the blade sections that has the content.
We can do other many interesting stuff on the blade templates such as below…
@extends('layouts.app')
@section('content')
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<h1>Hi user</h1>
<!--Display Data-->
Hello, {{ $name }}.
Your controller should be as follows
UserController.php
public function index() {
return view('user', ['name' => 'Brian'], compact('users'));
}
<!--get data from database-->
@forelse ($users as $user)
<li>{{ $user->name }}</li>
<li>{{ $user->email }}</li>
@empty
<p>No users</p>
@endforelse
UserController.php
public function index() {
$users = User::all();
return view('user);
}
other features
<!--check if user is authenticated-->
@auth
The user is authenticated...
@endauth
@guest
The user is not authenticated...
@endguest
</br>
<!--Using if statement-->
@if (count($users) === 1)
I have one user!
@elseif (count($users) > 1)
I have multiple users!
@else
I don't have any users!
@endif
Ensure you create a database in the phpmyadmin or the server you are using same as the one created in the laravel framework then run php artisan migrate to migrate the user tables.
We also have other features in the blade template we may look at them in the future.
- Validation:
With Laravel validation, we can validate any content in laravel like title, body, images on a blog website. Here are the steps
Make a post.blade.php as follows and paste the code below
post.blade.php
@extends('layouts.app')
@section('content')
<div class ="text">
<h1 class="heading">This is the page for all the posts</h1>
</div>
@if(Session::has('message'))
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>
{{ Session('message') }}
</div>
@endif
<div class="card-body">
<table class="table table-bordered mb-0">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Title</th>
<th scope="col">Body</th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
<td>{{ $post->body }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
This is just a simple table made with bootstrap where we can display the title and body of the post.
Let’s create a blade template for creating a post where we will validate the post title and body.
create.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">Post - create</div>
<div class="card-body">
{!! Form::open(['route' => 'posts.store']) !!}
<div class="form-group @if($errors->has('title')) has-error @endif">
{!! Form::label('Title') !!}
{!! Form::text('title', null, ['class' => 'form-control', 'placeholder' => 'title']) !!}
@if ($errors->has('title'))
<span class="help-block">{!! $errors->first('title') !!}</span>@endif
</div>
<div class="form-group @if($errors->has('body')) has-error @endif">
{!! Form::label('body') !!}
{!! Form::text('body', null, ['class' => 'form-control', 'placeholder' => 'body']) !!}
@if ($errors->has('body'))
<span class="help-block">{!! $errors->first('body') !!}</span>@endif
</div>
{!! Form::submit('Create',['class' => 'btn btn-sm btn-primary']) !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
Now the code in create.blade.php has a form from laravel collective so for us to use it run the command below to add it to laravel framework.
composer require laravelcollective/html
Now we are ready to use the form.
From the create.blade.php we route to posts.store where the title and body of our post gets validated and created so we will create a PostsController
PostsController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class PostsController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$posts = Post::orderBy('id', 'DESC')->get();
return view('post', compact('posts'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
],
[
'title.required' => 'Enter the title',
'body.required' => 'Enter the body',
]
);
$post = new Post();
$post->title = $request->title;
$post->body = $request->body;
$post->save();
Session::flash('message', 'Post created successfully');
return redirect()->route('posts.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
return 'post Id:'. $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)
{
//
}
}
Remember we created the PostsController at the start of our tutorial by running the command php artisan make:controller PostsController –resource
We are validating the post title and body before it gets created in the database. Take note of the post function create a view method, this enables us to create the post having the route posts.create.
In the web.php you should have this route Route::resource(‘posts’, PostsController::class); then run php artisan route:list to inspect the routes created.
Lastly create a model Post.php to connect to our database by running the command php artisan make:model Post.php and paste the code below
Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'body'];
}
Create the posts table
php artisan make:migration create_posts_table
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->unique();
$table->text('body');
$table->timestamps();
});
Finally, run
php artisan migrate
Need to add the php artisan migrate after running migration for the posts
Yes, thanks!
Thank You can I have the MySql table to follow the tutorial?
Welcome, yes let me send it to your email…
Pingback: Laravel Multi Authentication - Webdev Trainee
Pingback: Laravel Livewire Crud - Webdev Trainee
Pingback: Laravel Livewire Tutorial - Webdev Trainee
Pingback: Laravel 9 Open AI PHP Client - Webdev Trainee
Pingback: The Laravel Pennant - Webdev Trainee
Pingback: Laravel 10 Crash Course For Beginners. - Webdev Trainee