> For the complete documentation index, see [llms.txt](https://tony915.gitbook.io/laravel-4-2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tony915.gitbook.io/laravel-4-2/dong-shou-zuo-jin-jie/form-validation.md).

# Form 的資料驗證

一般來說，我們會先在前端使用 JavaScript 做基本的資料檢查，但是我們也都知道，有心人士是可以跳過這個檢查，直接將資料送到後端的，所以後端的資料驗證是不可少的必要動作。

## Controller 的部份

Laravel 包含了一個 Validator 類別，專門用來處理資料驗證。

使用 Validator 類別的 make() 方法來建立驗證：

```
Validator::make(data, rules, messages, customAttributes)
```

* data：陣列。是準備要驗證的資料，也就是表單送過來的資料。
* rules：陣列。驗證規則。
* messages：陣列。驗證失敗後要回傳的訊息。
* customAttributes：自定屬性，可省略。

除了 data 及 rules，後面的兩個參數都可省略。

在迷你部落格的例子中，我們要驗證標題是否有填寫資料。首先，打開 app/controllers/HomeController.php，修改 store() 方法，加入驗證：

```
public function store()
{
    $input = Input::all();

    $rules = ['title' => 'required'];
    $messages = ['required' => '! 欄位不能空白'];

    $validator = Validator::make($input, $rules, $messages);

    if ($validator->passes()){
        $post = new Post;
        $post->title = $input['title'];
        $post->content = $input['content'];
        $post->save();

        return Redirect::to('post');
    }

    return Redirect::to('post/create')
            ->withInput()
            ->withErrors($validator);
}
```

說明：

Input::all() 會取得表單欄位及資料，以陣列的方式儲存，像這樣：

```
['title'=>'標題輸入的文字',
'content'=>'內容輸入的文字']
```

將它送給 Validator::make() 的第一個參數。

接著我們建立驗證規則：

```
$rules = ['title' => 'required'];
```

* title：是表單欄位的名稱。
* required：是關鍵字，表示這個欄位為必填，也就是不能空白。

註：可以在官網查詢更多的[驗證規則關鍵字](http://laravel.com/docs/4.2/validation#available-validation-rules)\[1]。

有了驗證規則，再來就是要指定，當驗證發生錯誤時，要回傳的錯誤訊息：

```
$messages = ['required' => '! 欄位不能空白'];
```

required 為關鍵字，對應到驗證規則裡所有指定為 required 的項目。值就是要顯示的訊息。

當 $validator->passes() 為 true 時，表示通過驗證，這時候才進行資料庫操作的動作。相反地，如果 $validator->fails() 為 true，表示驗證失敗，不做任何動作並返回表單頁面。

在驗證未過，返回表單頁面的同時，可以同時回傳使用者輸入的資料及錯誤訊息：

```
return Redirect::to('post/create')
            ->withInput()
            ->withErrors($validator);
```

重導頁面到 post/create 也就是表單頁面。withInput() 會同時把使用者有輸入資料的欄位的值回傳，所以回到表單頁面時，欄位中會有使用者剛剛填寫的資料，而不是空空的。withErrors() 則是把驗證結果回傳，這個動作會把錯誤訊息放入 session 中，View 在收到這個訊息時就可以顯示出來。

## View 的部份

編輯 app/views/site/create.blade.php，在原本的：

```
{{Form::text('title')}}<br>
```

下方，增加錯誤訊息的區塊：

```
{{ Form::text('title') }}
@if ($errors->has('title'))
    <div style="color:red;">{{ $errors->first('title') }}</div>
@endif
<br>
```

$errors 是 MessageBag 類別的實體。基本上，$errors 存在於每個 view 中，我們可以在有需要的時候才去呼叫它。而為什麼 $errors 會有我們回傳的 $validator 中的訊息呢？因為 Laravel 自動將它們綁定(bind)了。

檢查 $errors->has('title') 如果有資料才顯示我們的錯誤訊息 $errors->first('title')。

好了，你現在試著不要在標題中輸入任何資料，然後按"發表文章"按鈕，看看有沒有在欄位下方出現錯誤訊息。

另外可以試看看，當標題是空的，但是有輸入內容時，送出資料會發生什麼事？在標題顯示錯誤訊息的同時，內容的資料會被保留。假設你把 HomeController\@store 中的 ->withInput() 這一行拿掉，做同樣的動作，內容欄位就會被清空，而沒有被保留。

## 同一欄位，多個驗證規則

要對同一欄位加入多個驗證規則，每個規則必須用直線( | )分隔。

我們讓標題除了不能空白，還必須輸入超過 5 個字，在 HomeController\@store 中改兩行：

```
$rules = ['title' => 'required|min:5'];
$messages = ['required' => '! 欄位不能空白', 'min' => '! 必須超過5個字'];
```

min 是關鍵字，後面接數字。min:5 表示字數最少要 5 個字。同樣用 min 關鍵字設定錯誤訊息。

這樣就完成了，view 完全都不用改。現在標題輸入一個字，就會出現新的錯誤訊息了。

* \[1] <http://laravel.com/docs/4.2/validation#available-validation-rules>
