鍍金池/ 教程/ PHP/ 新手入門指南-簡單任務(wù)管理系統(tǒng)
門面
Laravel Homestead
安裝及配置
測試
HTTP 中間件
加密
升級指南
幫助函數(shù)
應(yīng)用目錄結(jié)構(gòu)
集合
新手入門指南-簡單任務(wù)管理系統(tǒng)
任務(wù)調(diào)度
查詢構(gòu)建器
視圖
驗(yàn)證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊(duì)列
調(diào)整器
分頁
文件系統(tǒng)/云存儲
貢獻(xiàn)代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請求
Laravel Elixir
發(fā)行版本說明
Envoy 任務(wù)運(yùn)行器(SSH任務(wù))
序列化
Session
起步
帶用戶功能的任務(wù)管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務(wù)提供者
Blade 模板引擎
包開發(fā)
用戶認(rèn)證
Artisan 控制臺
HTTP 響應(yīng)
集合
服務(wù)容器
關(guān)聯(lián)關(guān)系
一次請求的生命周期
契約
Redis
錯誤&日志

新手入門指南-簡單任務(wù)管理系統(tǒng)

引言:Laravel 官方終于推出5.1版本快速入門指南了,學(xué)院君在 reddit 上看到大家的討論后才得知這一消息,立即著手進(jìn)行了翻譯,希望對 Laravel 學(xué)習(xí)者有所幫助。

1、簡介

快速入門指南會對 Laravel 框架做一個基本介紹,包括數(shù)據(jù)庫遷移、Eloquent ORM、路由、驗(yàn)證、視圖以及 Blade 模板等等。如果你是個 Laravel 新手甚至之前對 PHP 框架也很陌生,那么這里將會成為你的良好起點(diǎn)。如果你已經(jīng)使用過 Laravel 獲取其它 PHP 框架,可以考慮跳轉(zhuǎn)到進(jìn)階指南(翻譯中)。

為了演示 Laravel 特性的基本使用,我們將將會構(gòu)建一個簡單的、用于追蹤所有要完成任務(wù)的任務(wù)列表(To-Do List),本教程完整的代碼已經(jīng)公開在 Github 上:https://github.com/laravel/quickstart-basic。

2、安裝

當(dāng)然,開始之前你首先要做的是安裝一個新的 Laravel 應(yīng)用。你可以使用 Homestead 虛擬機(jī)或者本地 PHP 開發(fā)環(huán)境來運(yùn)行應(yīng)用。設(shè)置好開發(fā)環(huán)境后,可以使用如下 Composer 命令安裝應(yīng)用:

composer create-project laravel/laravel quickstart --prefer-dist

當(dāng)然你還可以通過克隆 GitHub 倉庫到本地來安裝:

git clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate

如果你還不了解如何構(gòu)建本地開發(fā)環(huán)境,可參考 Homestead 和安裝文檔。

3、準(zhǔn)備好數(shù)據(jù)庫

數(shù)據(jù)庫遷移

首先,讓我們使用遷移來定義數(shù)據(jù)表用于處理所有任務(wù)。Laravel 的數(shù)據(jù)庫遷移特性提供了一個簡單的方式來對數(shù)據(jù)表結(jié)構(gòu)進(jìn)行定義和修改:不需要讓團(tuán)隊(duì)的每個成員添加列到本地數(shù)據(jù)庫,只需要簡單運(yùn)行你提交到源碼控制中的遷移即可實(shí)現(xiàn)數(shù)據(jù)表創(chuàng)建及修改。

那么,讓我們來創(chuàng)建這個處理所有任務(wù)的數(shù)據(jù)表吧。Artisan 命令可以用來生成多種類從而節(jié)省重復(fù)的勞動,在本例中,我們使用 make:migration 命令生成 tasks 對應(yīng)的數(shù)據(jù)表遷移:

php artisan make:migration create_tasks_table --create=tasks

該命令生成的遷移文件位于項(xiàng)目根目錄下的 database/migrations 目錄,可能你已經(jīng)注意到了,make:migration 命令已經(jīng)在遷移文件中為我們添加了自增 ID 和時間戳,接下來我們要編輯該文件添加更多的列到數(shù)據(jù)表 tasks

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTasksTable extends Migration{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tasks');
    }
}

要運(yùn)行遷移,可以使用 Artisan 命令 migrate。如果你使用的是 Homestead,應(yīng)該在虛擬機(jī)中運(yùn)行該命令:

php artisan migrate

該命令會為我們創(chuàng)建遷移文件中定義的所有數(shù)據(jù)表,如果你使用數(shù)據(jù)庫客戶端軟件查看數(shù)據(jù)庫,可以看到已經(jīng)創(chuàng)建了一個新的 tasks 表,其中包含了我們在遷移中定義的列。接下來,我們準(zhǔn)備為這個數(shù)據(jù)表定義一個 Eloquent ORM 模型。

Eloquent 模型

Laravel 使用的默認(rèn) ORM 是 Eloquent,Eloquent 使用模型讓數(shù)據(jù)存取變得簡單和輕松,通常,每一個 Eloquent 模型都有一個與之對應(yīng)的數(shù)據(jù)表。

所以我們要定義一個與剛剛創(chuàng)建的 tasks 表對應(yīng)的 Task 模型,同樣我們使用 Artisan 命令來生成這個模型:

 php artisan make:model Task

該模型類位于 app 目錄下,默認(rèn)情況下,模型類是空的,我們不需要告訴該 Eloquent 模型對應(yīng)哪張數(shù)據(jù)表,這一點(diǎn)我們在 Eloquent 文檔中提及過,這里默認(rèn)對應(yīng)的數(shù)據(jù)表是 tasks,下面是這個空的模型類:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model{
    //
}

了解更多關(guān)于 Eloquent 模型類的細(xì)節(jié),可查看完整的 Eloquent 文檔。

4、路由

創(chuàng)建路由

下面我們需要為應(yīng)用定義一些路由,路由的作用是在用戶訪問指定頁面時將頁面URL匹配到被執(zhí)行的控制器或匿名函數(shù)。默認(rèn)情況下,所有的 Laravel 路由都定義在 app/Http/routes.php。

在本應(yīng)用中,我們需要至少三個路由:顯示所有任務(wù)的路由,添加新任務(wù)的路由,以及刪除已存在任務(wù)的路由。接下來,讓我們在 app/Http/routes.php 文件中創(chuàng)建這三個路由:

<?php

use App\Task;
use Illuminate\Http\Request;

/**
 * Display All Tasks
 */
Route::get('/', function () {
   //
});

/**
 * Add A New Task
 */
Route::post('/task', function (Request $request) {
    //
});

/**
 * Delete An Existing Task
 */
Route::delete('/task/{id}', function ($id) {
    //
});

顯示視圖

接下來,我們來填充/路由,在這個路由中,我們要渲染一個 HTML 模板,該模板包含添加新任務(wù)的表單,以及顯示任務(wù)列表。

在 Laravel 中,所有的 HTML 模板都存放在 resources/views 目錄下,我們可以使用 view 函數(shù)從路由中返回其中一個模板:

Route::get('/', function () {
    return view('tasks');
});

當(dāng)然,接下來我們需要去創(chuàng)建這個視圖。

5、創(chuàng)建布局&視圖

本應(yīng)用為了簡單處理只包含一個視圖,其中包含了添加新任務(wù)的表單和所有任務(wù)的列表。為了讓大家有一個直觀的視覺效果,我們貼出該視圖的截圖,可以看到我們在視圖中使用了基本的 Bootstrap CSS 樣式:

http://wiki.jikexueyuan.com/project/laravel-5.1/images/basic-overview.png" alt="" />

定義布局

幾乎所有的 web 應(yīng)用都是在不同頁面中共享同一個布局,例如,本應(yīng)用在視圖頂部有一個導(dǎo)航條,該導(dǎo)航條在每個頁面都會出現(xiàn)。Laravel 通過在每個頁面中使用 Blade 布局讓共享這些公共特性變得簡單。

正如我們之前討論的,所有 Laravel 視圖都存放在 resources/views 中,因此,我們在 resources/views/layouts/app.blade.php 中定義一個新的布局視圖,.blade.php 擴(kuò)展表明框架使用 Blade 模板引擎來渲染視圖,當(dāng)然,你可以使用原生的 PHP 模板,然而,Blade 提供了的標(biāo)簽語法可以幫助我們編寫更加清爽、簡短的模板。

編輯 app.blade.php 內(nèi)容如下:

// resources/views/layouts/app.blade.php
<!DOCTYPE html><html lang="en">
    <head>
        <title>Laravel Quickstart - Basic</title>

        <!-- CSS And JavaScript -->
    </head>

    <body>
        <div class="container">
            <nav class="navbar navbar-default">
                <!-- Navbar Contents -->
            </nav>
        </div>

        @yield('content')
    </body>
</html>

注意布局中的 @yield('content')部分,這是一個 Blade 指令,用于指定繼承布局的子頁面在這里可以注入自己的內(nèi)容。接下來,我們來定義使用該布局的子視圖來提供主體內(nèi)容。

定義子視圖

好了,我們已經(jīng)創(chuàng)建了應(yīng)用的布局視圖,下面我們需要定義一個包含創(chuàng)建新任務(wù)的表單和已存在任務(wù)列表的視圖,該視圖文件存放在 resources/views/tasks.blade.php

我們將跳過 Bootstrap CSS 的樣板文件而只專注在我們所關(guān)注的事情上,不要忘了,你可以從 GitHub 下載本應(yīng)用的所有資源:

// resources/views/tasks.blade.php

@extends('layouts.app')

@section('content')

    <!-- Bootstrap Boilerplate... -->

    <div class="panel-body">
        <!-- Display Validation Errors -->
        @include('common.errors')

        <!-- New Task Form -->
        <form action="/task" method="POST" class="form-horizontal">
            {{ csrf_field() }}

            <!-- Task Name -->
            <div class="form-group">
                <label for="task" class="col-sm-3 control-label">Task</label>

                <div class="col-sm-6">
                    <input type="text" name="name" id="task-name" class="form-control">
                </div>
            </div>

            <!-- Add Task Button -->
            <div class="form-group">
                <div class="col-sm-offset-3 col-sm-6">
                    <button type="submit" class="btn btn-default">
                        <i class="fa fa-plus"></i> Add Task
                    </button>
                </div>
            </div>
        </form>
    </div>

    <!-- TODO: Current Tasks -->
@endsection

在繼續(xù)往下之前,讓我們簡單談?wù)勥@個模板。首先,我們使用 @extends 指令告訴 Blade 我們要使用定義在 resources/views/layouts/app.blade.php 的布局,所有 @section('content')@endsection 之間的內(nèi)容將會被注入到 app.blade.php 布局的 @yield('contents')指令位置。

現(xiàn)在,我們已經(jīng)為應(yīng)用定義了基本的布局和視圖,接下來,我們準(zhǔn)備添加代碼到 POST /task 路由來處理添加新任務(wù)到數(shù)據(jù)庫。

注:@include('common.errors')指令將會加載 resources/views/common/errors.blade.php 模板中的內(nèi)容,我們還沒有定義這個模板,但很快就會了!

6、添加任務(wù)

驗(yàn)證表單輸入

現(xiàn)在我們已經(jīng)在視圖中定義了表單,接下來需要編寫代碼處理表單請求,我們需要驗(yàn)證表單輸入,然后才能創(chuàng)建一個新任務(wù)。

對這個表單而言,我們將 name 字段設(shè)置為必填項(xiàng),而且長度不能超過255個字符。如果表單驗(yàn)證失敗,將會跳轉(zhuǎn)到前一個頁面,并且將錯誤信息存放到一次性 session 中:

Route::post('/task', function (Request $request) {
    $validator = Validator::make($request->all(), [
        'name' => 'required|max:255',
    ]);

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

    // Create The Task...
});

$errors 變量

讓我們停下來討論下上述代碼中的->withErrors($validator)部分,->withErrors($validator)會將驗(yàn)證錯誤信息存放到一次性 session 中,以便在視圖中可以通過 $errors 變量訪問。

我們在視圖中使用了 @include('common.errors')指令來渲染表單驗(yàn)證錯誤信息,common.errors 允許我們在所有頁面以統(tǒng)一格式顯示錯誤信息。我們定義 common.errors 內(nèi)容如下:

// resources/views/common/errors.blade.php

@if (count($errors) > 0)
    <!-- Form Error List -->
    <div class="alert alert-danger">
        <strong>Whoops! Something went wrong!</strong>

        <br><br>

        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

注:$errors 變量在每個 Laravel 視圖中都可以訪問,如果沒有錯誤信息的話它就是一個空的 ViewErrorBag 實(shí)例。

創(chuàng)建任務(wù)

現(xiàn)在輸入驗(yàn)證已經(jīng)做好了,接下來正式開始創(chuàng)建一個新任務(wù)。一旦新任務(wù)創(chuàng)建成功,頁面會跳轉(zhuǎn)到/。要創(chuàng)建任務(wù),可以使用 Eloquent 模型提供的 use 方法:

Route::post('/task', function (Request $request) {
    $validator = Validator::make($request->all(), [
        'name' => 'required|max:255',
    ]);

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

    $task = new Task;
    $task->name = $request->name;
    $task->save();

    return redirect('/');
});

好了,到了這里,我們已經(jīng)可以成功創(chuàng)建任務(wù),接下來,我們繼續(xù)添加代碼到視圖來顯示所有任務(wù)列表。

顯示已存在的任務(wù)

首先,我們需要編輯/路由傳遞所有已存在任務(wù)到視圖。view 函數(shù)接收一個數(shù)組作為第二個參數(shù),我們可以將數(shù)據(jù)通過該數(shù)組傳遞到視圖中:

Route::get('/', function () {
    $tasks = Task::orderBy('created_at', 'asc')->get();

    return view('tasks', [
        'tasks' => $tasks
    ]);
});

數(shù)據(jù)被傳遞到視圖后,我們可以在 tasks.blade.php 中以表格形式顯示所有任務(wù)。Blade 中使用@foreach 處理循環(huán)數(shù)據(jù):

@extends('layouts.app')

@section('content')
    <!-- Create Task Form... -->

    <!-- Current Tasks -->
    @if (count($tasks) > 0)
        <div class="panel panel-default">
            <div class="panel-heading">
                Current Tasks
            </div>

            <div class="panel-body">
                <table class="table table-striped task-table">

                    <!-- Table Headings -->
                    <thead>
                        <th>Task</th>
                        <th>&nbsp;</th>
                    </thead>

                    <!-- Table Body -->
                    <tbody>
                    @foreach ($tasks as $task)
                        <tr>
                            <!-- Task Name -->
                            <td class="table-text">
                                <div>{{ $task->name }}</div>
                            </td>

                            <td>
                                <!-- TODO: Delete Button -->
                            </td>
                        </tr>
                    @endforeach
                    </tbody>
                </table>
            </div>
        </div>
    @endif
@endsection

至此,本應(yīng)用基本完成。但是,當(dāng)任務(wù)完成時我們還沒有途徑刪除該任務(wù),接下來我們就來處理這件事。

7、刪除任務(wù)

添加刪除按鈕

我們在 tasks.blade.php 視圖中留了一個“TODO”注釋用于放置刪除按鈕。當(dāng)刪除按鈕被點(diǎn)擊時, DELETE /task 請求被發(fā)送到應(yīng)用后臺:

<tr>
    <!-- Task Name -->
    <td class="table-text">
        <div>{{ $task->name }}</div>
    </td>

    <!-- Delete Button -->
    <td>
        <form action="/task/{{ $task->id }}" method="POST">
            {{ csrf_field() }}
            {{ method_field('DELETE') }}

            <button>Delete Task</button>
        </form>
    </td>
</tr>

關(guān)于方法偽造

盡管我們使用的路由是 Route::delete,但我們在刪除按鈕表單中使用的請求方法為 POST,HTML 表單只支持 GETPOST 兩種請求方式,因此我們需要使用某種方式來偽造 DELETE 請求。

我們可以在表單中通過輸出 method_field('DELETE')來偽造 DELETE 請求,該函數(shù)生成一個隱藏的表單輸入框,然后 Laravel 識別出該輸入并使用其值覆蓋實(shí)際的 HTTP 請求方法。生成的輸入框如下:

<input type="hidden" name="_method" value="DELETE">

刪除任務(wù)

最后,讓我們添加業(yè)務(wù)邏輯到路由中執(zhí)行刪除操作,我們可以使用 Eloquent 提供的 findOrFail 方法從數(shù)據(jù)庫通過 ID 獲取模型實(shí)例,如果不存在則拋出404異常。獲取到模型后,我們使用模型的 delete 方法刪除該模型在數(shù)據(jù)庫中對應(yīng)的記錄。記錄被刪除后,跳轉(zhuǎn)到/頁面:

Route::delete('/task/{id}', function ($id) {
    Task::findOrFail($id)->delete();
    return redirect('/');
});
上一篇:郵件下一篇:遷移