Create PHP Laravel 10 CRUD Web App with MySQL

Last Updated on by in Laravel
Today we will be learning how to create a Laravel CRUD (Create, Read, Update, Delete) web application step by step from scratch.We will build a PHP based web application and also learn how to store data in MySQL database with Laravel PHP framework.

Beginner Laravel CRUD Example

We will create a student management CRUD app using PHP 7.3 and MySQL. In this app, a user can create, read, update, and delete the student’s data from the MySQL database using the Laravel framework.

Read More – Create Simple PHP 7|8 CRUD REST API with MySQL & PHP PDO

Laravel Advantages

Laravel is a PHP based web application framework with an eloquent, refined syntax. Developing an app with Laravel has loads of advantages; some of them are mentioned below.

  • Great Security
  • MVC Architecture
  • Database Migration
  • Simple Unit Testing
  • Improved Performance
  • Multi-lingual Support
  • Robust Authentication
  • Developer-friendly Code
  • Blade Templating Support
  • Object-Oriented Libraries
  • Open Source & Strong Community

Laravel is a free, open-source PHP web framework, created by Taylor Otwell and intended for the development of web applications following the model–view–controller (MVC) architectural pattern and based on Symfony. Some of the features of Laravel are a modular packaging system with a dedicated dependency manager, different ways for accessing relational databases, utilities that aid in application deployment and maintenance, and its orientation toward syntactic sugar.
wikipedia

Server Specification

The following are the server specifications to run the Laravel smoothly.

  • PHP >= 7.3.0
  • XML PHP Extension
  • PDO PHP Extension
  • JSON PHP Extension
  • Ctype PHP Extension
  • BCMath PHP Extension
  • OpenSSL PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension

Installing PHP Composer Package

Composer is a dependency manager for PHP libraries.

Head over to home directory:

cd ~

Next, run the following command to install the Composer using curl:

curl -sS https://getcomposer.org/installer -o composer-setup.php

Run the following command to install composer globally on your machine:

sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

By running the following command, you can identify the Composer version installed on your machine. However, we have installed Composer 1.9.

composer

This will be displayed on your terminal:

    ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.9.1 2019-11-01 17:20:17

Usage:
  command [options] [arguments]

Once the Composer is installed in your system, then you are ready to build a Laravel CRUD project.

Creating a Laravel Project

Go to your terminal and run the following command to build a Laravel project.

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

Get inside the project:

cd laravel-crud-app

Verify the installed Laravel app version:

php artisan -V

# Laravel Framework

Set Up MySQL Database

In this step, we will make the MySQL database connection in our PHP Laravel app. Following database variables need to be updated database name, username, password.

We must set up MySQL db before we get started with migrations. I assume you already know how to configure the database with PHPMyAdmin., Create the MySQL database give it a name something like laravel_db.

Once we are done creating a database, then we will insert MySQL db details in our .env file inside our Laravel CRUD app.

Laravel project contains the .env file, as the name suggests, It is a local where you keep all your database configurations, such as database credentials, mail driver details, cache drivers, etc.

However, it is not considered a good practice to store such credentials within the code directly. The .env files are not just limited to php; preferably, It is also utilized in different frameworks as well.

Now, a few essential points to be noted. If you make any changes in the .env configuration files, then you should restart the server.

In case you are using a virtual host, then you should run the following command via your terminal to clean the configuration cache.

php artisan config:clear

Open the .env file and place the following code in it:

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

If you are using MAMP on a macOS add the following line at the end of your .env configuration file.

DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock

Setting Up 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 the migration by adding the data properties in the MySQL table.

We need to create a Model and Migration file to create the migrations, run the following command.

php artisan make:model Student -m

Inside your Laravel project, you can check out migration files in the database/migrations 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 inside our migration file, open the migration file go to database/migrations/ timestamp_create_students_table.php file, and add the following schema inside of 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 files:

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

The down() function allows reversing an operation done by up method.

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

<?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 property is used inside the model, and it determines which data types or fields are mass-assignable in the database table.

Next, we have to run the following command to create the table in the database:

php artisan migrate

Creating Controller and Routes

Next, we are going to generate StudentController, run the below command to create a new controller for PHP CRUD app.

php artisan make:controller StudentController --resource

The above command generated a brand new file with this path app/Http/Controllers/StudentController.php. By default, there are seven methods defined in it, which are as follows:

  • index() => shows student list
  • create() => creates a student using a form
  • store() => creates a student in the database
  • show() => shows a specific student
  • edit() => updates the student data using a form
  • update() => updates the student data using a form
  • destroy() => removes a particular student

Now, we will start writing the code in StudentController.php file to initialize the CRUD operations for our PHP app.

<?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');
    }
}

Configure Routes

Add the following code in routes/web.php file:

<?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 the various routes for our CRUD app.

php artisan route:list
+--------+-----------+-------------------------+------------------+------------------------------------------------+------------+
| Domain | Method    | URI                     | Name             | Action                                         | Middleware |
+--------+-----------+-------------------------+------------------+------------------------------------------------+------------+
|        | GET|HEAD  | /                       |                  | Closure                                        | web        |
|        | GET|HEAD  | api/user                |                  | Closure                                        | api        |
|        |           |                         |                  |                                                | auth:api   |
|        | GET|HEAD  | students                | students.index   | App\Http\Controllers\StudentController@index   | web        |
|        | POST      | students                | students.store   | App\Http\Controllers\StudentController@store   | web        |
|        | GET|HEAD  | students/create         | students.create  | App\Http\Controllers\StudentController@create  | web        |
|        | GET|HEAD  | students/{student}      | students.show    | App\Http\Controllers\StudentController@show    | web        |
|        | PUT|PATCH | students/{student}      | students.update  | App\Http\Controllers\StudentController@update  | web        |
|        | DELETE    | students/{student}      | students.destroy | App\Http\Controllers\StudentController@destroy | web        |
|        | GET|HEAD  | students/{student}/edit | students.edit    | App\Http\Controllers\StudentController@edit    | web        |

Create Views in Laravel with Blade Templates

Now, we have to build the views for our student CRUD app with blade files. Go to resources/views folder and create the following blade templates in our Laravel project.

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

Configure Bootstrap in Laravel

Add the following code in the layout.blade.php template. Here, we defined the main layout for our app along with that we implemented Bootstrap UI framework via Stackpath CDN.

<!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>Laravel 8|7|6 CRUD App Example</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>

In the next step, we will also configure the following views template.

Create, Store & Validate User Data in MySQL Database

We have to create a form to create, store and validate a 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

To generate a new user, we are using cerate() mehtod, which is specified in the ShowController.php file.

// StudentController.php

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return view('create');
    }

    /**
     * Store a newly created resource in storage.
     */
    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!');
    }

laravel form validation

Once you click on the submit button, user data is written inside the students table in MySQL db.
store data in php mysql

Show Users Data

Now, we have to display the users’ data using the Bootstrap table. The index() function returns an index view with data retrieved from the mysql database. Add the given below code inside the index function.

// StudentController.php

 public function index()
    {
        $student = Student::all();
        return view('index', compact('student'));
    }

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

@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
  <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

Check this template on the following URL: http://127.0.0.1:8000/students/create

To show the user data in the tabular format, we are going to loop over the students’ array, and don’t forget to add edit and delete button to modify the Laravel app.

Edit and Update Data

To edit and update the user information, we are using the below functions in StudentController.php file.

// StudentController.php

     /**
     * Edit the specified resource.
     */
    public function edit($id)
    {
        $student = Student::findOrFail($id);
        return view('edit', compact('student'));
    }

    /**
     * Update the specified resource in db.
     */
    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');
    }

To edit and update data in MySQL database we are going to add the following code inside the resources/views/edit.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">
    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

Start the app in the browser by running the given below command:

php artisan serve

Check out the Laravel App Routes:

Create Student: http://127.0.0.1:8000/students/create

Students List: http://127.0.0.1:8000/students

Conclusion

We have finished Laravel CRUD operations and form validation tutorial with examples, to compare the code, you should check out my Github repository.