下面由Laravel教程欄目給大家介紹修改Laravel FormRequest驗證,實現(xiàn)場景驗證,希望對需要的朋友有所幫助!

在Laravel 中,很多創(chuàng)建和編輯的的接口都是需要做數(shù)據(jù)驗證的,對于數(shù)據(jù)驗證一般有2種方方式
在控制器里直接使用Request的validate方法
使用自定義FormRequest類,該類集成自Http\\Request
如果使用第一種方法,會比較亂,看起來不夠優(yōu)雅
但是如果使用第二種方式,那么針對每一種請求都要定義一個FormRequest
比如:ArticleStoreRequest和ArticleUpdateRequest
但是你會發(fā)現(xiàn)基本上驗證規(guī)則是一樣的,當然你可以在控制器方法里只注入一個Request,但是如果針對于一個Model 有多個Update的那種,比如用戶模塊,修改密碼/修改昵稱/修改頭像/修改地址/修改。。。怎么處理呢
所以這幾天針對這種情況,改進了下Laravel的Request機制,加了一個場景驗證
第一步:先創(chuàng)建一個AbstractRequest的基類<?php
namespace App\\Http\\Requests;
use Illuminate\\Foundation\\Http\\FormRequest;
use Illuminate\\Support\\Str;
/**
* 使用方法:
* Class AbstractRequest
* @package App\\Http\\Requests
*/
class AbstractRequest extends FormRequest
{
public $scenes = [];
public $currentScene; //當前場景
public $autoValidate = false; //是否注入之后自動驗證
public $extendRules;
public function authorize()
{
return true;
}
/**
* 設置場景
* @param $scene
* @return $this
*/
public function scene($scene)
{
$this->currentScene = $scene;
return $this;
}
/**
* 使用擴展rule
* @param string $name
* @return AbstractRequest
*/
public function with($name = '')
{
if (is_array($name)) {
$this->extendRules = array_merge($this->extendRules[], array_map(function ($v) {
return Str::camel($v);
}, $name));
} else if (is_string($name)) {
$this->extendRules[] = Str::camel($name);
}
return $this;
}
/**
* 覆蓋自動驗證方法
*/
public function validateResolved()
{
if ($this->autoValidate) {
$this->handleValidate();
}
}
/**
* 驗證方法
* @param string $scene
* @throws \\Illuminate\\Auth\\Access\\AuthorizationException
* @throws \\Illuminate\\Validation\\ValidationException
*/
public function validate($scene = '')
{
if ($scene) {
$this->currentScene = $scene;
}
$this->handleValidate();
}
/**
* 根據(jù)場景獲取規(guī)則
* @return array|mixed
*/
public function getRules()
{
$rules = $this->container->call([$this, 'rules']);
$newRules = [];
if ($this->extendRules) {
$extendRules = array_reverse($this->extendRules);
foreach ($extendRules as $extendRule) {
if (method_exists($this, "{$extendRule}Rules")) { //合并場景規(guī)則
$rules = array_merge($rules, $this->container->call(
[$this, "{$extendRule}Rules"]
));
}
}
}
if ($this->currentScene && isset($this->scenes[$this->currentScene])) {
$sceneFields = is_array($this->scenes[$this->currentScene])
? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);
foreach ($sceneFields as $field) {
if (array_key_exists($field, $rules)) {
$newRules[$field] = $rules[$field];
}
}
return $newRules;
}
return $rules;
}
/**
* 覆蓋設置 自定義驗證器
* @param $factory
* @return mixed
*/
public function validator($factory)
{
return $factory->make(
$this->validationData(), $this->getRules(),
$this->messages(), $this->attributes()
);
}
/**
* 最終驗證方法
* @throws \\Illuminate\\Auth\\Access\\AuthorizationException
* @throws \\Illuminate\\Validation\\ValidationException
*/
protected function handleValidate()
{
if (!$this->passesAuthorization()) {
$this->failedAuthorization();
}
$instance = $this->getValidatorInstance();
if ($instance->fails()) {
$this->failedValidation($instance);
}
}
}第二步:針對用戶Request,我們只需要定義一個UserRequest繼承AbstractRequest<?php
namespace App\\Http\\Requests;
class UserRequest extends AbstractRequest
{
public $scenes = [
'nickname' => 'nickname',
'avatar' => 'avatar',
'password' => 'password',
'address' => 'province_id,city_id'
];
public function rules()
{
return [ //全部的驗證規(guī)則
'mobile' => [],
'nickname' => [],
'password' => [
'required', 'min:6', 'max:16'
],
'avatar' => [],
'province_id' => [],
'city_id' => [],
//...
];
}
public function passwordRules()
{
return [
'password' => [
'required', 'min:6', 'max:16', 'different:$old_password' //修改新密碼不和舊密碼相同,此處只是舉例子,因為密碼需要Hash處理才能判斷是否相同
]
];
}
}控制器方法 UserController<?php
namespace App\\Http\\Controllers;
use App\\Http\\Requests\\UserRequest;
class UserController
{
public function register(UserRequest $request)
{
$request->validate(); //默認不設置場景 全部驗證
//...
}
public function updateAddress($id, UserRequest $request)
{
$request->scene('address')->validate();
//...
}
public function updateAvatar($id, UserRequest $request)
{
$request->validate('avatar');
//...
}
public function updatePassword($id, UserRequest $request)
{
//設置password場景,只驗證password字段,并且使用新的password規(guī)則替換原來的password規(guī)則
$request->scene('password')
->with('password')
->validate();
//...
}
}該方法沒有修改Laravel的核心驗證邏輯,只讓在FormRequest在注入到Controller的時候不要做自動驗證,當然,如果需要自動驗證,那么設置$autoValidate = true即可。
以上內(nèi)容僅供參考。望輕噴。
同時還有我也修改了ORM的場景驗證規(guī)則,可以在model里設置經(jīng)常,同時滿足多場景創(chuàng)建和更新
新聞標題:教你修改LaravelFormRequest驗證,實現(xiàn)場景驗證
分享鏈接:http://chinadenli.net/article30/cgjppo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供服務器托管、手機網(wǎng)站建設、App設計、用戶體驗、外貿(mào)建站、網(wǎng)站維護
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)