PHP Laravel 9 CRUD Web App Tutorial with MySQL

This time we will learn how to create a CRUD (Create, Read, Update, Delete) website application system with Laravel 9 step by step from scratch.

Here we will also learn how to store data in a MySQL database with the Laravel 9 PHP framework. I’m using PHP version 8.1.2 and laravel 9

we will create a student management CRUD application using PHP 8.1.2 and MySQL. In this application, users can create, read, update and delete student data from MySQL database using Laravel 9 framework.

Here I assume you have installed composer and laravel 9, and PHP version 8.1.2 if not, please follow the tutorial here

TABLE OF CONTENTS

  1. Creating a Laravel 9 Project
  2. Creating MySQL Databases
  3. Creating Migration and Model
  4. Creating Controllers and Routes
  5. Creating Views in Laravel with Blade Templates
  6. CRUD System Testing
  7. Closing
  1. CREATING A LARAVEL 9 PROJECT

If you are using xampp, please enter the htdocs directory via the command prompt as shown below:

then run the code below:

composer create-project laravel/laravel --prefer-dist laravel-crud-app

after that go to the project directory that we just created with the command “cd laravel-crud-app” as shown below:

next is verify the installed laravel version by typing the code “php artisan -V” as shown below:

 

2. CREATING MySQL DATABASE

Here I assume you already know how to configure a database with PHPMyAdmin., Create a MySQL database named like “db_laravel”

Once we’ve finished creating the database, we’ll include the MySQL db details in our .env file inside our Laravel 9 CRUD application.

The Laravel project contains an .env file, as the name suggests, This is the locale where you store all your database configurations, such as database credentials, email driver details, driver cache, etc.

Note: If you make changes to the .env configuration file, you will have to restart the server. by using the command “php artisan config: clear” as shown below:

now we will edit the .env file which contains the database settings and put the following code in it

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_laravel
DB_USERNAME=root
DB_PASSWORD=

here the only thing that needs to be changed is the database name in this line “DB_DATABASE=db_laravel”, db_laravel is the name of the database we just created in MySQL, because I didn’t use a password so I left it blank for the DB_PASSWORD line, but if you use a password please fill in the line “DB_PASSWORD”

 

3. CREATING MIGRATION AND MODEL

we have created the database and configured the database by adding the credentials in the env file. Now, we will learn how to set up a migration by adding data properties in MySQL tables.

Now we will create a Model and Migration file to create a Migration, run the following command:

“php artisan make:model Student -m”

Inside our Laravel project, we can inspect the migration files in the database/migration folder. By default Laravel generates the following files:

timestamp__create_users_table.php
timestamp_create_password_resets_table.php
timestamp_create_failed_jobs_table.php

Next we will add the schema in our migration file, open the migration file go to database/migrations/ timestamp_create_students_table.php file, and add the below code to it.

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStudentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('students', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email');
            $table->string('phone');
            $table->string('password');            
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('students');
    }
}

 

As you can see, there are two types of functions inside the migration/timestamp_create_students_table.php file:

The up() function allows creating/updating tables, columns, and indexes.

The down() function allows reversing operations performed by the up method.

Next, we will add the $fillable property in the Student model, open the app/Models/Student.php file and add the code below.

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
    use HasFactory;
    protected $fillable = ['name', 'email', 'phone', 'password'];
}

Fillable properties are used in the model, and determine which data types or fields can be enumerated in a database table.

Next, we have to run the following command to create a table in the database as shown below:

php artisan migrate

 

4. CREATING CONTROLLERS AND ROUTES

Next, we will create a StudentController, run the command below to create a new controller for the PHP CRUD application.

 

4.1 Creating a Controller

Run the following code “php artisan make:controller StudentController –resource”

Open the file app/Http/Controllers/StudentController.php then put the code below:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Student;

class StudentController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $student = Student::all();
        return view('index', compact('student'));
    }
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('create');
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $storeData = $request->validate([
            'name' => 'required|max:255',
            'email' => 'required|max:255',
            'phone' => 'required|numeric',
            'password' => 'required|max:255',
        ]);
        $student = Student::create($storeData);
        return redirect('/students')->with('completed', 'Student has been saved!');
    }
    /**
     * 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)
    {
        $student = Student::findOrFail($id);
        return view('edit', compact('student'));
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $updateData = $request->validate([
            'name' => 'required|max:255',
            'email' => 'required|max:255',
            'phone' => 'required|numeric',
            'password' => 'required|max:255',
        ]);
        Student::whereId($id)->update($updateData);
        return redirect('/students')->with('completed', 'Student has been updated');
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $student = Student::findOrFail($id);
        $student->delete();
        return redirect('/students')->with('completed', 'Student has been deleted');
    }
}

 

4.2 Creating Routes

open the routes/web.php file then put the code below and save it :

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\StudentController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::resource('students', StudentController::class);

Run the following command to create various routes for our CRUD application.

“php artisan route:list” will appear as shown below

 

5. CREATING VIEWS IN LARAVEL WITH BLADE TEMPLATES

Now it’s time to create a view for our student CRUD application with blade files. Go to the resources/views folder and create the following blade template in our Laravel project.

layout.blade.php
index.blade.php
create.blade.php
edit.blade.php

  • Create a layout.blade.php file (resources/views/layout.blade.php) then put the following code
<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>SISTEM CRUD DENGAN LARAVEL 9 </title>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
   </head>
   <body>
      <div class="container">
         @yield('content')
      </div>
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" type="text/js"></script>
   </body>
</html>

 

  • Create a file create.blade.php (resources/views/create.blade.php) then put the following code

In the next step, we will also configure a template for the Create, Store & Validate User Data in MySQL Database view.
We have to create a form to create, save, and validate user data using Bootstrap Form and Card UI components.

Add the following code in the resources/views/create.blade.php file

@extends('layout')
@section('content')
<style>
    .container {
      max-width: 450px;
    }
    .push-top {
      margin-top: 50px;
    }
</style>
<div class="card push-top">
  <div class="card-header">
    Add User
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
      <form method="post" action="{{ route('students.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Name</label>
              <input type="text" class="form-control" name="name"/>
          </div>
          <div class="form-group">
              <label for="email">Email</label>
              <input type="email" class="form-control" name="email"/>
          </div>
          <div class="form-group">
              <label for="phone">Phone</label>
              <input type="tel" class="form-control" name="phone"/>
          </div>
          <div class="form-group">
              <label for="password">Password</label>
              <input type="text" class="form-control" name="password"/>
          </div>
          <button type="submit" class="btn btn-block btn-danger">Create User</button>
      </form>
  </div>
</div>
@endsection

If the above code is run in a browser with the URL http://127.0.0.1:8000/students/create, you will get a display like the image below

.

  • Create a file index.blade.php (resources/views/index.blade.php) then put the following code
@extends('layout')
@section('content')
<style>
  .push-top {
    margin-top: 50px;
  }
</style>
<div class="push-top">
  @if(session()->get('success'))
    <div class="alert alert-success">
      {{ session()->get('success') }}  
    </div><br />
  @endif
  <div style="margin-bottom:20px">SISTEM CRUD DENGAN LARAVEL 9 <div style="float:right"><a href="http://127.0.0.1:8000/students/create">CREATE</a> - <a href="http://127.0.0.1:8000/students">DATA LIST</a></div></div>

  <table class="table">
    <thead>
        <tr class="table-warning">
          <td>ID</td>
          <td>Name</td>
          <td>Email</td>
          <td>Phone</td>
          <td>Password</td>
          <td class="text-center">Action</td>
        </tr>
    </thead>
    <tbody>
        @foreach($student as $students)
        <tr>
            <td>{{$students->id}}</td>
            <td>{{$students->name}}</td>
            <td>{{$students->email}}</td>
            <td>{{$students->phone}}</td>
            <td>{{$students->password}}</td>
            <td class="text-center">
                <a href="{{ route('students.edit', $students->id)}}" class="btn btn-primary btn-sm"">Edit</a>
                <form action="{{ route('students.destroy', $students->id)}}" method="post" style="display: inline-block">
                    @csrf
                    @method('DELETE')
                    <button class="btn btn-danger btn-sm"" type="submit">Delete</button>
                  </form>
            </td>
        </tr>
        @endforeach
    </tbody>
  </table>
<div>
@endsection

Create a file edit.blade.php (resources/views/edit.blade.php) then put the following code

@extends('layout')
@section('content')
<style>
    .container {
      max-width: 450px;
    }
    .push-top {
      margin-top: 50px;
    }
</style>
<div class="card push-top">
  <div class="card-header">
    Edit & Update
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
      <form method="post" action="{{ route('students.update', $student->id) }}">
          <div class="form-group">
              @csrf
              @method('PATCH')
              <label for="name">Name</label>
              <input type="text" class="form-control" name="name" value="{{ $student->name }}"/>
          </div>
          <div class="form-group">
              <label for="email">Email</label>
              <input type="email" class="form-control" name="email" value="{{ $student->email }}"/>
          </div>
          <div class="form-group">
              <label for="phone">Phone</label>
              <input type="tel" class="form-control" name="phone" value="{{ $student->phone }}"/>
          </div>
          <div class="form-group">
              <label for="password">Password</label>
              <input type="text" class="form-control" name="password" value="{{ $student->password }}"/>
          </div>
          <button type="submit" class="btn btn-block btn-danger">Update User</button>
      </form>
  </div>
</div>
@endsection

6. CRUD SYSTEM TESTING

Ok, we have finished creating 4 views, namely layout.blade.php, index.blade.php, create.blade.php and edit.blade.php next we will try to run our project in the browser.

go to our project directory via the command prompt (CMD) then type the following command in “php artisan serve” as shown below

after that we open the browser and type the url “http://127.0.0.1:8000/students/” then if there is no error it will appear as shown below

here I have entered 3 user data, so if you don’t have the data, you can enter new user data via the URL “http://127.0.0.1:8000/students/create” and a form will appear as shown below

try to enter new data and then check the data that we input is entered or not via the URL “http://127.0.0.1:8000/students/” if the process is successful then the data will appear as shown below

to edit the data press the “Edit” button in the “action” column if there is no error it will appear as shown below

then click the “Update User” button to save the newly edited data, to delete the data we can press the “Delete” button in the “Action” column.

 

7. CLOSING

Thus the process of making a CRUD system using PHP version 8.1.2, Laravel version 9 and MySQL database, hopefully it will be useful.