[TOC]
### **1、簡介**
快速[入門指南](http://laravelacademy.org/tags/%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97 "View all posts in 入門指南")會對[Laravel](http://laravelacademy.org/tags/laravel "View all posts in Laravel")框架做一個基本介紹,包括數據庫遷移、Eloquent ORM、[路由](http://laravelacademy.org/tags/%e8%b7%af%e7%94%b1 "View all posts in 路由")、[驗證](http://laravelacademy.org/tags/%e9%aa%8c%e8%af%81 "View all posts in 驗證")、[視圖](http://laravelacademy.org/tags/%e8%a7%86%e5%9b%be "View all posts in 視圖")以及[Blade](http://laravelacademy.org/tags/blade "View all posts in Blade")模板等等。如果你是個Laravel新手甚至之前對PHP框架也很陌生,那么這里將會成為你的良好起點。如果你已經使用過Laravel獲取其它PHP框架,可以考慮跳轉到進階指南(翻譯中)。
為了演示Laravel特性的基本使用,我們將將會構建一個簡單的、用于追蹤所有要完成任務的任務列表(To-Do List),本[教程](http://laravelacademy.org/tags/%e6%95%99%e7%a8%8b "View all posts in 教程")完整的代碼已經公開在Github上:[https://github.com/laravel/quickstart-basic](https://github.com/laravel/quickstart-basic)。
### **2、安裝**
##### **安裝Laravel**
當然,開始之前你首先要做的是安裝一個新的Laravel應用。你可以使用[Homestead虛擬機](http://laravelacademy.org/post/2749.html)或者本地PHP開發環境來運行應用。設置好開發環境后,可以使用如下Composer命令安裝應用:
~~~
composer?create-project?laravel/laravel?quickstart?--prefer-dist
~~~
##### **安裝Quickstart項目**
當然你還可以通過克隆GitHub倉庫到本地來安裝:
~~~
git clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate
~~~
如果你還不了解如何構建本地開發環境,可參考[Homestead](http://laravelacademy.org/post/2749.html)和[安裝](http://laravelacademy.org/post/2720.html)[文檔](http://laravelacademy.org/tags/%e6%96%87%e6%a1%a3 "View all posts in 文檔")。
### **3、準備好數據庫**
#### **3.1 數據庫遷移**
首先,讓我們使用遷移來定義數據表用于處理所有任務。Laravel的數據庫遷移特性提供了一個簡單的方式來對數據表結構進行定義和修改:不需要讓團隊的每個成員添加列到本地數據庫,只需要簡單運行你提交到源碼控制中的遷移即可實現數據表創建及修改。
那么,讓我們來創建這個處理所有任務的數據表吧。[Artisan命令](http://laravelacademy.org/post/3106.html)可以用來生成多種類從而節省重復的勞動,在本例中,我們使用`make:migration`命令生成`tasks`對應的數據表遷移:
~~~
php artisan make:migration create_tasks_table --create=tasks
~~~
該命令生成的遷移文件位于項目根目錄下的`database/migrations`目錄,可能你已經注意到了,`make:migration`命令已經在遷移文件中為我們添加了自增ID和時間戳,接下來我們要編輯該文件添加更多的列到數據表`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');
}
}
~~~
要運行遷移,可以使用Artisan命令`migrate`。如果你使用的是Homestead,應該在虛擬機中運行該命令:
~~~
php artisan migrate
~~~
該命令會為我們創建遷移文件中定義的所有數據表,如果你使用數據庫客戶端軟件查看數據庫,可以看到已經創建了一個新的`tasks`表,其中包含了我們在遷移中定義的列。接下來,我們準備為這個數據表定義一個Eloquent ORM[模型](http://laravelacademy.org/tags/%e6%a8%a1%e5%9e%8b "View all posts in 模型")。
#### **3.2 Eloquent模型**
Laravel使用的默認ORM是Eloquent,[Eloquent](http://laravelacademy.org/post/2995.html)使用模型讓數據存取變得簡單和輕松,通常,每一個Eloquent模型都有一個與之對應的數據表。
所以我們要定義一個與剛剛創建的`tasks`表對應的`Task`模型,同樣我們使用Artisan命令來生成這個模型:
~~~
php artisan make:model Task
~~~
該模型類位于`app`目錄下,默認情況下,模型類是空的,我們不需要告訴該Eloquent模型對應哪張數據表,這一點我們在[Eloquent 文檔](http://laravelacademy.org/post/2995.html)中提及過,這里默認對應的數據表是`tasks`,下面是這個空的模型類:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model{
//
}
~~~
了解更多關于Eloquent模型類的細節,可查看完整的[Eloquent文檔](http://laravelacademy.org/post/2995.html)。
### **4、路由**
#### **4.1 路由存根**
下面我們需要為應用定義一些路由,路由的作用是在用戶訪問指定頁面時將頁面URL匹配到被執行的控制器或匿名函數。默認情況下,所有的Laravel路由都定義在`app/Http/routes.php`。
在本應用中,我們需要至少三個路由:顯示所有任務的路由,添加新任務的路由,以及刪除已存在任務的路由。接下來,讓我們在`app/Http/routes.php`文件中創建這三個路由:
~~~
<?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) {
//
});
~~~
#### **4.2 顯示視圖**
接下來,我們來填充`/`路由,在這個路由中,我們要渲染一個HTML模板,該模板包含添加新任務的[表單](http://laravelacademy.org/tags/%e8%a1%a8%e5%8d%95 "View all posts in 表單"),以及顯示任務列表。
在Laravel中,所有的HTML模板都存放在`resources/views`目錄下,我們可以使用`view`函數從路由中返回其中一個模板:
~~~
Route::get('/',?function?()?{
return?view('tasks');
});
~~~
傳遞tasks到view函數將會創建一個對應視圖模板為 resources/views/tasks.blade.php的View對象。接下來我們需要去創建這個視圖文件。
### **5、創建布局&視圖**
本應用為了簡單處理只包含一個視圖,其中包含了添加新任務的表單和所有任務的列表。為了讓大家有一個直觀的視覺效果,我們貼出該視圖的截圖,可以看到我們在視圖中使用了基本的Bootstrap CSS樣式:

#### **5.1 定義布局**
幾乎所有的web應用都是在不同頁面中共享同一個布局,例如,本應用在視圖頂部有一個導航條,該導航條在每個頁面都會出現。Laravel通過在每個頁面中使用Blade布局讓共享這些公共特性變得簡單。
正如我們之前討論的,所有Laravel視圖都存放在`resources/views`中,因此,我們在`resources/views/layouts/app.blade.php`中定義一個新的布局視圖,`.blade.php`擴展表明框架使用[Blade模板引擎](http://laravelacademy.org/post/2865.html)來渲染視圖,當然,你可以使用原生的PHP模板,然而,Blade提供了的標簽語法可以幫助我們編寫更加清爽、簡短的模板。
編輯`app.blade.php`內容如下:
~~~
// 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指令,用于指定繼承布局的子頁面在這里可以注入自己的內容。接下來,我們來定義使用該布局的子視圖來提供主體內容。
#### **[5.2](http://laravelacademy.org/tags/5-2 "View all posts in 5.2")?定義子視圖**
好了,我們已經創建了應用的布局視圖,下面我們需要定義一個包含創建新任務的表單和已存在任務列表的視圖,該視圖文件存放在`resources/views/tasks.blade.php`。
我們將跳過Bootstrap CSS的樣板文件而只專注在我們所關注的事情上,不要忘了,你可以從[GitHub](https://github.com/laravel/quickstart-basic)下載本應用的所有資源:
~~~
//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
~~~
##### **一些需要注意的事項**
在繼續往下之前,讓我們簡單談談這個模板。首先,我們使用`@extends`指令告訴Blade我們要使用定義在`resources/views/layouts/app.blade.php`的布局,所有`@section('content')`和`@endsection`之間的內容將會被注入到`app.blade.php`布局的`@yield('contents')`指令位置。
現在,我們已經為應用定義了基本的布局和視圖,接下來,我們準備添加代碼到`POST /task`路由來處理添加新任務到數據庫。
`@include('common.errors')`指令將會加載`resources/views/common/errors.blade.php`模板中的內容,我們還沒有定義這個模板,但很快就會了!
現在我們為應用定義了基本布局和視圖文件,現在我們回到/路由:
~~~
Route::get('/',?function?()?{
return?view('tasks');
});
~~~
接下來,我們準備添加代碼到`POST /task`路由以便處理輸入并添加新任務到數據庫。
### **6、添加任務**
#### **6.1 驗證**
現在我們已經在視圖中定義了表單,接下來需要在POST /task路由中編寫代碼處理表單請求,我們需要驗證表單輸入,然后才能創建一個新任務。
對這個表單而言,我們將`name`字段設置為必填項,而且長度不能超過255個字符。如果表單驗證失敗,將會跳轉到前一個頁面,并且將錯誤信息存放到一次性[Session](http://laravelacademy.org/post/3261.html)中:
~~~
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)`會將驗證錯誤信息存放到一次性session中,以便在視圖中可以通過`$errors`變量訪問。
我們在視圖中使用了`@include('common.errors')`指令來渲染表單驗證錯誤信息,`common.errors`允許我們在所有頁面以統一格式顯示錯誤信息。我們定義`common.errors`內容如下:
~~~
// 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`實例。
#### **6.2 創建任務**
現在輸入驗證已經做好了,接下來正式開始創建一個新任務。一旦新任務創建成功,頁面會跳轉到`/`。要創建任務,可以使用Eloquent模型提供的`save`方法:
~~~
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('/');
});
~~~
好了,到了這里,我們已經可以成功創建任務,接下來,我們繼續添加代碼到視圖來顯示所有任務列表。
#### **6.3 顯示已存在的任務**
首先,我們需要編輯`/`路由傳遞所有已存在任務到視圖。`view`函數接收一個數組作為第二個參數,我們可以將數據通過該數組傳遞到視圖中:
~~~
Route::get('/', function () {
$tasks = Task::orderBy('created_at', 'asc')->get();
return view('tasks', [
'tasks' => $tasks
]);
});
~~~
數據被傳遞到視圖后,我們可以在`tasks.blade.php`中以表格形式顯示所有任務。Blade中使用`@foreach`處理循環數據:
~~~
@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> </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
~~~
至此,本應用基本完成。但是,當任務完成時我們還沒有途徑刪除該任務,接下來我們就來處理這件事。
### **7、刪除任務**
#### **7.1 添加刪除按鈕**
我們在`tasks.blade.php`視圖中留了一個“TODO”注釋用于放置刪除按鈕。當刪除按鈕被點擊時,`DELETE /task`請求被發送到應用后臺:
~~~
<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>
~~~
##### **關于方法偽造**
盡管我們使用的路由是`Route::delete`,但我們在刪除按鈕表單中使用的請求方法為`POST`,HTML表單只支持`GET`和`POST`兩種請求方式,因此我們需要使用某種方式來偽造`DELETE`請求。
我們可以在表單中通過輸出`method_field('DELETE')`來偽造`DELETE`請求,該函數生成一個隱藏的表單輸入框,然后Laravel識別出該輸入并使用其值覆蓋實際的HTTP請求方法。生成的輸入框如下:
~~~
<input type="hidden" name="_method" value="DELETE">
~~~
#### **7.2 刪除任務**
最后,讓我們添加業務邏輯到路由中執行刪除操作,我們可以使用Eloquent提供的`findOrFail`方法從數據庫通過ID獲取模型實例,如果不存在則拋出404異常。獲取到模型后,我們使用模型的`delete`方法刪除該模型在數據庫中對應的記錄。記錄被刪除后,跳轉到`/`頁面:
~~~
Route::delete('/task/{id}', function ($id) {
Task::findOrFail($id)->delete();
return redirect('/');
});
~~~
- 序言
- 發行版本說明
- 升級指南
- 貢獻代碼
- 開始
- 安裝
- 配置
- Laravel Homestead
- 基礎
- HTTP 路由
- HTTP 中間件
- HTTP 控制器
- HTTP 請求
- HTTP 響應
- 視圖
- Blade 模板引擎
- 架構
- 一次請求的生命周期
- 應用目錄結構
- 服務提供者
- 服務容器
- 門面(Facades)
- 數據庫
- 起步
- 查詢構建器
- 遷移
- 填充數據
- Eloquent ORM
- 起步
- 關聯關系
- 集合
- 訪問器&修改器
- 序列化
- 服務
- 用戶認證
- 用戶授權
- Artisan Console
- 訂閱支付實現:Laravel Cashier
- 緩存
- 集合
- 集成前端資源:Laravel Elixir
- 加密
- 錯誤&日志
- 事件
- 文件系統/云存儲
- 哈希
- 輔助函數
- 本地化
- 郵件
- 包開發
- 分頁
- Redis
- 隊列
- Session
- Envoy Task Runner
- 任務調度
- 測試
- 驗證
- 新手入門指南
- 簡單任務管理系統
- 帶用戶功能的任務管理系統