驗證是 Laravel Eloquent 模型的特徵,可確保模型在保存之前符合其驗證標準。如果它們被認為無效,則不會保存模型並且將提供驗證錯誤。
驗證允許多個規則集,將模型 ID 注入到unique
驗證規則中,並在驗證失敗時引發異常。它小巧而靈活,適合您的工作流程,並幫助您僅保存有效數據。
希望在 Laravel 4.2+ 上使用驗證?查看 0.10.x 分支以取得文件和安裝說明。
Laravel 4.2 版本較適合做表單驗證;它支援自訂驗證訊息、確認規則和多個規則集。因為 Laravel 5.0 具有FormRequest
驗證,所以驗證現在旨在保持核心資料有效並將表單驗證留給框架。
想要在 Laravel 5.0 到 5.2 上使用驗證?查看 2.x 分支以取得文件和安裝說明。
Laravel 5.0 - 5.2 版本使用了 Laravel 框架中已棄用的ValidationException
合約。對於 Laravel 5.3,我們現在擴展了核心驗證ValidationException
,這意味著當發生驗證錯誤時,框架將自動重定向回錯誤,就像FormRequest
一樣。
請繼續閱讀 - 這些說明適合您!
只需前往composer.json
檔案所在的專案目錄並輸入:
作曲家需要沃森/驗證
查看 Laravel 4.2+ 的安裝說明。查看 Laravel 5.0 - 5.2 的安裝說明。
首先,將特徵新增至您的模型中,並根據需要新增驗證規則和訊息。
使用 WatsonValidatingValidatingTrait;class Post 擴展了 Eloquent { 使用 ValidatingTrait; protected $rules = [ 'title' => '必需', 'slug' => '必需|unique:posts,slug', 'content' => '必需' ]; }
如果您使用的是 BaseModel 並且它將適用於從它擴展的所有模型,您還可以將該特徵添加到BaseModel
中,否則您可以只擴展WatsonValidatingValidatingModel
而不是Eloquent
。
注意:您需要在從使用該特徵的BaseModel
擴充功能的任何模型上設定$rules
屬性,或設定空數組作為BaseModel
的$rules
。如果不這樣做,您將不可避免地出現LogicException with message 'Relationship method must return an object of type IlluminateDatabaseEloquentRelationsRelation'
。
現在,您可以使用一些令人愉悅的功能。
// 檢查模型是否有效。 // true// 或檢查是否無效。 // false// 一旦確定了模型的有效性,// 您就可以獲得錯誤。 // 錯誤訊息包
模型驗證也變得非常簡單。
if ( ! $post->save()) {// Oops.return redirect()->route('posts.create') ->withErrors($post->getErrors()) ->withInput(); }返回重定向()->路由('posts.show', $post->id) ->withSuccess("您的貼文已成功儲存。");
否則,如果您在驗證模型時更喜歡使用異常,則可以使用saveOrFail()
方法。現在,當您嘗試儲存無效模型時,將會引發異常。
$post->saveOrFail();
如果您不想,則無需捕獲異常。 Laravel 知道如何處理ValidationException
並會自動重新導向回表單輸入和錯誤。如果您想自己處理,也可以。
嘗試 {$post->saveOrFail(); } catch (WatsonValidatingValidationException $e) {$errors = $e->getErrors();回傳redirect()->route('posts.create') ->withErrors($errors) ->withInput(); }
請注意,您可以將異常傳遞給withErrors()
方法,例如withErrors($e)
,Laravel 將知道如何處理它。
如果您正在使用該模型並且希望執行繞過驗證的保存,則可以。這將傳回與在沒有特徵的模型上呼叫save()
相同的結果。
$post->forceSave();
如果您希望在使用save()
方法時預設拋出異常,而不是必須使用saveOrFail()
您可以在模型或BaseModel
上設定下列屬性。
/** * 如果模型驗證失敗,是否應拋出 ValidationException。如果不設置,則預設為 false。 * * @var boolean */protected $throwValidationExceptions = true;
如果您想要使用例外狀況或傳回值執行一次性儲存,可以使用saveOrFail()
和saveOrReturn
方法。
若要顯示自訂驗證錯誤訊息,只需將$validationMessages
屬性新增至模型中即可。
/** * 要傳遞給驗證器的驗證訊息。 * * @var array */protected $validationMessages = ['slug.unique' => "另一篇文章已經在使用該 slug。"];
您可能已經注意到,我們在 slug 上使用了unique
規則,如果我們更新持久模型,則該規則將無法運作。幸運的是,驗證將為您處理這個問題,並將模型的主鍵附加到規則中,以便規則按預期工作;忽略當前模型。
您可以透過在模型上設定$injectUniqueIdentifier
屬性來調整此功能。
/** * 模型是否應在嘗試驗證之前將其識別碼注入到唯一的 * 驗證規則中。如果模型中未設定此屬性*,它將預設為 true。 * * @var boolean */protected $injectUniqueIdentifier = true;
開箱即用,我們支援 Laravel 提供的unique
規則。我們也支援流行的 felixkiss/uniquewith-validator 規則,但您需要選擇加入。只需在匯入驗證特徵後加入use WatsonValidatingInjectorsUniqueWithInjector
即可。
如果您願意,支援其他注入規則也很容易。假設您想要支援名為unique_ids
附加規則,該規則僅採用模型的主鍵(無論出於何種原因)。您只需新增一個駝峰式規則,該規則接受任何現有參數和欄位名稱,並傳回替換規則。
/** * 準備一個 unique_ids 規則,如果需要,請新增模型識別碼。 * * @param array $parameters * @param string $field * @return string */受保護的函數prepareUniqueIdsRule($parameters, $field) {// 僅當模型已持久化時才執行替換。 $this->getKey(); }返回'unique_ids'; }
在這種情況下,如果模型已儲存且主鍵為10
,則規則unique_ids
將替換為unique_ids:10
。
在驗證過程中,該特徵會觸發各種事件,您可以掛鉤這些事件來影響驗證過程。
要掛鉤,您首先需要將$observeables
屬性新增到您的模型(或基本模型)上。這只是讓 Eloquent 知道您的模型可以回應這些事件。
/** * 使用者公開的可觀察事件 * * @var array */protected $observables = ['validating', 'validated'];
當驗證即將發生時, eloquent.validating: ModelName
事件將被觸發,其中$event
參數將saving
或restoring
。例如,如果您要更新命名空間模型AppUser
事件將為eloquent.validating: AppUser
。如果您偵聽這些事件中的任何一個並傳回一個值,則可以阻止驗證完全發生。
event::listen('eloquent.validating:*', function($model, $event) {// 偽俄羅斯輪盤賭validation.if (rand(1, 6) === 1) {return false; } });
驗證發生後,您還可以掛鉤一系列validated
事件,例如passed
、 failed
和skipped
事件。對於上面驗證失敗的範例,您可以獲得事件eloquent.validated: AppUser
。
目前 Laravel 中存在一個錯誤(請參閱問題 #1181),該錯誤會阻止模型事件在測試套件中多次觸發。這意味著使用模型測試的第一個測試將通過,但任何後續測試都將失敗。該線程中列出了幾個臨時解決方案,您可以使用它們同時使測試通過。
由於 Laravel 出於追蹤 bug 和拉取請求的目的已改用 Liferaft,因此上述問題可能無法解決。這個要點有一個範例TestCase.php
,它向您展示如何在測試之間重置所有模型的事件,以便它們可以按預期工作。
您可以透過多種方式在控制器中使用驗證模型,但這裡有一個使用 Laravel 5 中新的 FormRequest 的範例(如果您想查看另一個沒有 FormRequest 的控制器範例,請檢查該軟體包的4.2+ 版本。
此範例允許 FormRequest 處理表單驗證並允許模型處理其自身的驗證,從而保持程式碼整潔。透過啟用驗證異常,您可以減少重複的控制器程式碼(try/catch 區塊)並全域處理模型驗證異常(您的表單請求應保持模型有效,因此如果您的模型無效,則這是一個異常事件)。
<?php 命名空間 AppHttpControllers;use AppHttpRequestsPostFormRequest;use IlluminateRoutingController;class PostsController 擴充 Controller {受保護的$post;公用函式__construct(Post $post) {$這個->post = $post; }// ...公用函數儲存(PostFormRequest $request) {// 如果 Post 無效,則會拋出異常。 .show', $post); } }
然後,您可以在app/Exceptions/Handler.php
中捕獲模型驗證異常並根據需要進行處理。
公用函數渲染($ request,異常$ e) {if ($e instanceof WatsonValidatingValidationException) {return back()->withErrors($e)->withInput(); }parent::render($request, $e); }