在這個面向初學者的教程中,我們將學習如何使用最新的PHP開發框架 Laravel 5.8,來創建一個基於MySQL數據庫的Web應用,實現聯繫人的 增刪改查功能。
1、安裝PHP環境
Laravel 5.8 要求PHP 7.1+,mysql>5.7.7,因此我們需要先安裝最新版的PHP。在大多數 系統上這個過程都很簡單。
1.1 安裝PHP7.1
在ubuntu上執行以下命令:
1 2 3 |
~$ sudo add-apt-repository ppa:ondrej/php ~$ sudo apt-get update ~$ sudo apt-get install php7.1 |
如果你的ubuntu版本是18.04,那麼默認的軟件倉裏就包含了PHP7.2,因此可以 直接安裝:
1 |
~$ sudo apt-get install php |
1.2 安裝必要的PHP模塊
Laravel 5.8需要一些擴展模塊,可以使用下面的命令安裝:
1 |
~ $ 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 安裝PHP Composer
現在讓我們開始安裝Composer,PHP的包管理器。
從官網下載安裝程序然後進行安裝:
1 2 |
~$ curl -sS https://getcomposer.org/installer -o composer-setup.php ~$ sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer |
使用下面的命令驗證composer的安裝:
1 |
~$ composer |
應該可以看到如下輸出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/ ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ 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、初始化Laravel 5.8項目
生成一個Laravel 5.8項目非常簡單,在終端輸入如下命令:
1 |
~$ composer create-project --prefer-dist laravel/laravel crud-app |
上述命令將安裝laravel 5.8.3。可以使用下面的命令來驗證安裝的版本:
1 2 3 |
~$ cd crud-app ~/crud-app$ php artisan -V Laravel Framework 5.8.19 |
3、安裝Laravel項目的前端依賴庫
在生成的Laravel項目中,package.json文件包含了前端依賴庫的描述信息,例如:
- axios
- bootstrap
- cross-env
- jquery
- laravel-mix
- lodash
- popper.js
- resolve-url-loader
- sass
- sass-loader
- vue
使用npm命令安裝這些前端依賴庫:
1 |
~/crud-app$ npm install |
npm命令執行完之後,在目錄中將會出現node_modules目錄。
4、創建MySQL數據庫
現在我們來創建一個MySQL數據庫來保存數據。在終端啓動mysql客戶端 並在提示時輸入密碼,然後進入mysql控制檯:
1 |
~$ mysql -u root -p |
在mysql控制檯輸入下面的SQL語句創建db數據庫:
1 |
mysql> create database db; |
打開.env文件來更新訪問MySQL數據庫的賬號信息:
1 2 3 4 5 6 |
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=db DB_USERNAME=root DB_PASSWORD=****** |
現在,可以運行migrate
命令來創建Laravel需要的SQL數據表了:
1 |
~/crud-app$ php artisan migrate |
5、創建第一個Laravel模型
Laravel使用MVC架構模式來將應用解耦爲三個部分:
- 模型Model用來封裝數據訪問層
- 視圖View用來封裝表示層
- 控制器Controller用來封裝應用控制代碼並負責模型和視圖的通信
現在讓我們來創建第一個Laravel模型,在終端輸入如下命令:
1 |
~/crud-app$ php artisan make:model Contact --migration |
上面的命令將創建一個Contact模型以及一個遷移文件,在終端中我們得到 類似下面這樣的輸出:
1 2 |
Model created successfully. Created Migration: 2019_01_27_193840_create_contacts_table |
打開遷移文件database/migrations/xxxxxx_create_contacts_table進行 相應的更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?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'); } } |
我們再contracts表中添加這些字段:first_name、last_name、email、job_title、 city 和 country 。
現在可以使用下面的命令在數據庫中創建contracts表:
1 |
~/crud-app$ php artisan migrate |
現在讓我們看一下Contract模型,我們將使用它來和contracts數據表交互。打開 app/Contact.php 並參考以下內容進行更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Contact extends Model { protected $fillable = [ 'first_name', 'last_name', 'email', 'city', 'country', 'job_title' ]; } |
6、創建Laravel控制器和路由
在創建模型並執行數據遷移後,現在我們創建與Contract模型協同工作的 控制器和路由。在終端運行下面的命令:
1 |
~/crud-app$ php artisan make:controller ContactController --resource |
打開app/Http/Controllers/ContactController.php,初始內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<?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) { // } } |
ContractController類繼承自Laravel的Controller類,並且定義了 一組方法用於對Contact模型的CRUD操作。現在我們需要實現這些方法。 不過在實現這些方法之前,讓我們先添加路由。
打開routes/web.php,參考如下內容進行修改:
1 2 3 4 5 6 |
<?php Route::get('/', function () { return view('welcome'); }); Route::resource('contacts', 'ContactController'); |
使用Route的resource()靜態方法,你可以創建多個路由來暴露 資源的多種訪問操作。這些路由都映射到ContactController的不同 方法上(我們隨後將實現這些方法):
- GET/contacts:映射到index()方法
- GET /contacts/create:映射到create()方法
- POST /contacts:映射到store() 方法
- GET /contacts/{contact}:映射到show()方法
- GET /contacts/{contact}/edit: 映射到edit()方法
- PUT/PATCH /contacts/{contact}:映射到update()方法
- DELETE /contacts/{contact}:映射到destroy()方法
這些路由用於提供HTML模板,同時也用作Contract模型的API端結點。
7、實現CRUD操作
現在讓我們實現控制器的方法。
7.1 C - Create/創建操作
ContactController包含了映射到POST /contracts
端結點的store()
方法, 該方法將用來在數據庫中創建一個聯繫人/contact,映射到GET / contracts/create
的create()
方法將用來提供HTML表單。仙子我們來實現這兩個方法。
首先重新打開app/Http/Controllers/ContactController.php ,導入Contact模型:
1 |
use App\Contact; |
接下來,找到store()方法進行如下修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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!'); } |
然後,找到create()方法進行如下修改:
1 2 3 4 |
public function create() { return view('contacts.create'); } |
create()
函數使用view()
方法來返回reousrces/view
目錄中的create.blade.php
模板。
在創建create.blade.php
模板之前,我們需要創建一個基礎模板,create以及本教程中的 其他模板都將繼承這個基礎模板。
在resources/views
目錄中,創建base.blade.php
文件:
1 2 |
~/crud-app$ cd resources/views ~/crud-app$ touch base.blade.php |
打開resources/views/base.blade.php,添加如下模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!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> |
現在我們創建create.blade.php模板。首先在views目錄創建一個contracts文件夾:
1 |
~/crud-app/views$ mkdir contacts |
然後創建模板:
1 2 |
~/crud-app/views$ cd contacts ~/crud-app/views/contacts$ touch create.blade.php |
打開resources/views/contacts/create.blade.php,添加如下代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
@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 |
表單效果如下:
7.2R - Read/讀取操作
現在讓我們讀取並顯示MySQL數據庫中的聯繫人信息。
打開app/Http/Controllers/ContactController.php文件,找到index()
方法並進行 如下修改:
1 2 3 4 5 6 |
public function index() { $contacts = Contact::all(); return view('contacts.index', compact('contacts')); } |
接下來創建index模板resources/views/contacts.index.blade.php:
1 |
~/crud-app/views/contacts$ touch index.blade.php |
打開resources/views/contacts/index.blade.php 添加如下代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
@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/更新操作
現在我們實現數據更新操作。打開app/Http/Controllers/ContactController.php 文件,找到edit($id)方法進行如下更新:
1 2 3 4 5 |
public function edit($id) { $contact = Contact::find($id); return view('contacts.edit', compact('contact')); } |
接下來我們實現update()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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!'); } |
現在需要添加edit模板,在resources/views/contacts/目錄中創建edit.blade.php文件:
1 |
~/crud-app/views/contacts$ touch edit.blade.php |
打開文件resources/views/contacts/edit.blade.php,添加如下代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
@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/刪除操作
最後我們要實現刪除操作。打開app/Http/Controllers/ContactController.php文件, 找到destroy() 方法,然後進行如下的更新:
1 2 3 4 5 6 7 |
public function destroy($id) { $contact = Contact::find($id); $contact->delete(); return redirect('/contacts')->with('success', 'Contact deleted!'); } |
容易注意到CRUD API方法中重定向到/contacts路由時,傳入了一個index模板中沒有 的消息,現在讓我們來修改。
打開resources/views/contacts/index.blade.php文件,找到如下代碼:
1 2 3 4 5 6 7 8 |
<div class="col-sm-12"> @if(session()->get('success')) <div class="alert alert-success"> {{ session()->get('success') }} </div> @endif </div> |
我們還需要添加一個按鈕:
1 2 3 |
<div> <a style="margin: 19px;" href="{{ route('contacts.create')}}" class="btn btn-primary">New contact</a> </div> |
頁面效果如下:
原文鏈接:Laravel 5.8 Tutorial: Build your First CRUD App with Laravel and MySQL (PHP 7.1+)