In this beginner-oriented tutorial, we will learn how to use the latest PHP development framework, Laravel 5.8, to create a Web application based on MySQL database, to achieve the function of adding, deleting and modifying contacts.
If you want to quickly grasp the development of block chain applications, we recommend Hui Zhi's. A series of tutorials on block chain application and development It covers many block chains, such as bitcoin, Ethernet workshop, eos, super-book fabric s and tendermint, as well as java, go, nodejs, python, php, dart and other development languages.
1. Installing PHP Environment
Laravel 5.8 requires PHP 7.1+, so we need to install the latest version of PHP first. This process is simple on most systems.
1.1 Install PHP 7.1
Execute the following commands on ubuntu:
~$ sudo add-apt-repository ppa:ondrej/php ~$ sudo apt-get update ~$ sudo apt-get install php7.1
If your ubuntu version is 18.04, PHP 7.2 is included in the default software repository, so you can install it directly:
~$ sudo apt-get install php
1.2 Install the necessary PHP modules
Laravel 5.8 requires some extension modules, which can be installed using the following commands:
~ $ sudo apt-get install php7.1 php7.1-cli php7.1-common php7.1-json php7.1-opcache php7.1-mysql php7.1-mbstring php7.1-mcrypt php7.1-zip php7.1-fpm php7.1-xml
1.3 Install PHP Composer
Now let's start installing Composer, PHP's package manager.
Download the installer from the official website and install it:
~$ curl -sS https://getcomposer.org/installer -o composer-setup.php ~$ sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
Verify the installation of composer with the following commands:
~$ composer
You should see the following output:
/ ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.8.0 2018-12-03 10:31:16 Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --profile Display timing and memory usage information --no-plugins Whether to disable plugins. -d, --working-dir=WORKING-DIR If specified, use the given directory as working directory. -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
2. Initialization of Laravel 5.8 Project
Generating a Laravel 5.8 project is very simple. Enter the following commands at the terminal:
~$ composer create-project --prefer-dist laravel/laravel crud-app
The above command will install laravel 5.8.3. The following commands can be used to validate the installed version:
~$ cd crud-app ~/crud-app$ php artisan -V Laravel Framework 5.8.19
3. Installing front-end dependency libraries for Laravel projects
In the generated Laravel project, the package.json file contains descriptive information about the front-end dependency libraries, such as:
- axios
- bootstrap
- cross-env
- jquery
- laravel-mix
- lodash
- popper.js
- resolve-url-loader
- sass
- sass-loader
- vue
Install these front-end dependency libraries using the npm command:
~/crud-app$ npm install
After the npm command is executed, the node_modules directory will appear in the directory.
4. Create MySQL database
Now let's create a MySQL database to store data. Start the MySQL client at the terminal and enter the password when prompted, then enter the MySQL console:
~$ mysql -u root -p
Enter the following SQL statement in the mysql console to create the db database:
mysql> create database db;
Open the. env file to update account information accessing MySQL database:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=db DB_USERNAME=root DB_PASSWORD=******
Now you can run the migrate command to create the SQL tables Laravel needs:
~/crud-app$ php artisan migrate
5. Create the first Laravel model
Laravel uses the MVC architecture pattern to decouple applications into three parts:
- Model Model is used to encapsulate data access layer
- View View View is used to encapsulate the presentation layer
- Controller is used to encapsulate application control code and to communicate between model and view.
Now let's create the first Laravel model and enter the following commands at the terminal:
~/crud-app$ php artisan make:model Contact --migration
The above command will create a Contact model and a migration file. In the terminal, we get output like the following:
Model created successfully. Created Migration: 2019_01_27_193840_create_contacts_table
Open the migration file database/migrations/xxxx_create_contacts_table to update accordingly:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateContactsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('contacts', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->string('first_name'); $table->string('last_name'); $table->string('email'); $table->string('job_title'); $table->string('city'); $table->string('country'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('contacts'); } }
We add these fields to the contracts table: first_name, last_name, email, job_title, city and country.
Now you can use the following command to create contracts tables in the database:
~/crud-app$ php artisan migrate
Now let's look at the Contract model, which we'll use to interact with the contracts data table. Open app/Contact.php and update it with reference to the following:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Contact extends Model { protected $fillable = [ 'first_name', 'last_name', 'email', 'city', 'country', 'job_title' ]; }
6. Creating Laravel Controller and Routing
After creating the model and performing data migration, we now create controllers and routes that work in collaboration with the Contract model. Run the following command at the terminal:
~/crud-app$ php artisan make:controller ContactController --resource
Open app/Http/Controllers/ContactController.php, starting with the following:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class ContactController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * 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) { // } /** * 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) { // } }
The ContractController class inherits from Laravel's Controller class and defines a set of methods for CRUD operations on the Contact model. Now we need to implement these methods. But before we implement these methods, let's add routing first.
Open routes/web.php and modify it with reference to the following:
<?php Route::get('/', function () { return view('welcome'); }); Route::resource('contacts', 'ContactController');
Using Route's resource() static method, you can create multiple routes to expose multiple access operations to resources. These routes are mapped to different methods of ContactController (which we will implement later):
- GET/contacts: Mapping to index() method
- GET/contacts/create: Mapping to create() method
- POST/contacts: Mapping to store() method
- GET/contacts/{contact}: Mapping to show() method
- GET/contacts/{contact}/edit: Mapping to edit() method
- PUT/PATCH/contacts/{contact}: Mapping to update() method
- DELETE/contacts/{contact}: Mapping to destroy() method
These routes are used to provide HTML templates as well as API endpoints for the Control model.
7. Implementing CRUD Operation
Now let's implement the controller method.
7.1 C - Create / Create operation
ContactController contains a store() method mapped to POST/contracts endpoints, which will be used to create a contact in the database and a create() method mapped to GET/contracts/create to provide HTML forms. Fairy, we implement these two methods.
First, reopen app/Http/Controllers/ContactController.php and import the Contact model:
use App\Contact;
Next, find the store() method and make the following modifications:
public function store(Request $request) { $request->validate([ 'first_name'=>'required', 'last_name'=>'required', 'email'=>'required' ]); $contact = new Contact([ 'first_name' => $request->get('first_name'), 'last_name' => $request->get('last_name'), 'email' => $request->get('email'), 'job_title' => $request->get('job_title'), 'city' => $request->get('city'), 'country' => $request->get('country') ]); $contact->save(); return redirect('/contacts')->with('success', 'Contact saved!'); }
Then, find the create() method and make the following modifications:
public function create() { return view('contacts.create'); }
The create() function uses the view() method to return the create.blade.php template in the reousrces/view directory.
Before creating the create.blade.php template, we need to create a base template, which will be inherited by create and other templates in this tutorial.
In the resources/views directory, create the base.blade.php file:
~/crud-app$ cd resources/views ~/crud-app$ touch base.blade.php
Open resources/views/base.blade.php and add the following template:
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Laravel 5.8 & MySQL CRUD Tutorial</title> <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" /> </head> <body> <div class="container"> @yield('main') </div> <script src="{{ asset('js/app.js') }}" type="text/js"></script> </body> </html>
Now let's create the create.blade.php template. First create a contracts folder in the views directory:
~/crud-app/views$ mkdir contacts
Then create the template:
~/crud-app/views$ cd contacts ~/crud-app/views/contacts$ touch create.blade.php
Open resources/views/contacts/create.blade.php and add the following code:
@extends('base') @section('main') <div class="row"> <div class="col-sm-8 offset-sm-2"> <h1 class="display-3">Add a contact</h1> <div> @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('contacts.store') }}"> @csrf <div class="form-group"> <label for="first_name">First Name:</label> <input type="text" class="form-control" name="first_name"/> </div> <div class="form-group"> <label for="last_name">Last Name:</label> <input type="text" class="form-control" name="last_name"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" name="email"/> </div> <div class="form-group"> <label for="city">City:</label> <input type="text" class="form-control" name="city"/> </div> <div class="form-group"> <label for="country">Country:</label> <input type="text" class="form-control" name="country"/> </div> <div class="form-group"> <label for="job_title">Job Title:</label> <input type="text" class="form-control" name="job_title"/> </div> <button type="submit" class="btn btn-primary-outline">Add contact</button> </form> </div> </div> </div> @endsection
The effect of the form is as follows:
7.2R - Read / Read Operation
Now let's read and display contact information in MySQL database.
Open the app/Http/Controllers/ContactController.php file, find the index() method and make the following modifications:
public function index() { $contacts = Contact::all(); return view('contacts.index', compact('contacts')); }
Next, create the index template resources/views/contacts.index.blade.php:
~/crud-app/views/contacts$ touch index.blade.php
Open resources/views/contacts/index.blade.php and add the following code:
@extends('base') @section('main') <div class="row"> <div class="col-sm-12"> <h1 class="display-3">Contacts</h1> <table class="table table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> <td>Email</td> <td>Job Title</td> <td>City</td> <td>Country</td> <td colspan = 2>Actions</td> </tr> </thead> <tbody> @foreach($contacts as $contact) <tr> <td>{{$contact->id}}</td> <td>{{$contact->first_name}} {{$contact->last_name}}</td> <td>{{$contact->email}}</td> <td>{{$contact->job_title}}</td> <td>{{$contact->city}}</td> <td>{{$contact->country}}</td> <td> <a href="{{ route('contacts.edit',$contact->id)}}" class="btn btn-primary">Edit</a> </td> <td> <form action="{{ route('contacts.destroy', $contact->id)}}" method="post"> @csrf @method('DELETE') <button class="btn btn-danger" type="submit">Delete</button> </form> </td> </tr> @endforeach </tbody> </table> <div> </div> @endsection
7.3 U - Update / Update Operation
Now we implement the data update operation. Open the app/Http/Controllers/ContactController.php file and find the edit($id) method to update as follows:
public function edit($id) { $contact = Contact::find($id); return view('contacts.edit', compact('contact')); }
Next we implement the update() method:
public function update(Request $request, $id) { $request->validate([ 'first_name'=>'required', 'last_name'=>'required', 'email'=>'required' ]); $contact = Contact::find($id); $contact->first_name = $request->get('first_name'); $contact->last_name = $request->get('last_name'); $contact->email = $request->get('email'); $contact->job_title = $request->get('job_title'); $contact->city = $request->get('city'); $contact->country = $request->get('country'); $contact->save(); return redirect('/contacts')->with('success', 'Contact updated!'); }
Now you need to add the edit template to create the edit.blade.php file in the resources/views/contacts/directory:
~/crud-app/views/contacts$ touch edit.blade.php
Open the file resources/views/contacts/edit.blade.php and add the following code:
@extends('base') @section('main') <div class="row"> <div class="col-sm-8 offset-sm-2"> <h1 class="display-3">Update a contact</h1> @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('contacts.update', $contact->id) }}"> @method('PATCH') @csrf <div class="form-group"> <label for="first_name">First Name:</label> <input type="text" class="form-control" name="first_name" value={{ $contact->first_name }} /> </div> <div class="form-group"> <label for="last_name">Last Name:</label> <input type="text" class="form-control" name="last_name" value={{ $contact->last_name }} /> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" name="email" value={{ $contact->email }} /> </div> <div class="form-group"> <label for="city">City:</label> <input type="text" class="form-control" name="city" value={{ $contact->city }} /> </div> <div class="form-group"> <label for="country">Country:</label> <input type="text" class="form-control" name="country" value={{ $contact->country }} /> </div> <div class="form-group"> <label for="job_title">Job Title:</label> <input type="text" class="form-control" name="job_title" value={{ $contact->job_title }} /> </div> <button type="submit" class="btn btn-primary">Update</button> </form> </div> </div> @endsection
7.4 D - Delete / Delete operation
Finally, we need to implement the deletion operation. Open the app/Http/Controllers/ContactController.php file, find the destroy() method, and then update it as follows:
public function destroy($id) { $contact = Contact::find($id); $contact->delete(); return redirect('/contacts')->with('success', 'Contact deleted!'); }
It's easy to notice that when redirecting to / contacts routing in the CRUD API method, a message that is not in the index template is passed in. Now let's modify it.
Open the resources/views/contacts/index.blade.php file and find the following code:
<div class="col-sm-12"> @if(session()->get('success')) <div class="alert alert-success"> {{ session()->get('success') }} </div> @endif </div>
We also need to add a button:
<div> <a style="margin: 19px;" href="{{ route('contacts.create')}}" class="btn btn-primary">New contact</a> </div>
The effect of the page is as follows:
Links to the original text: Laravel 5.8 Concise Tutorial - Huizhi