目前的 validate 是不支援 scene 類似的策略的,這使我在開發中是相當不便利。
在業務編寫的過程中 總結出了 一套目前為止我比較滿意的解決方案 分享給大家。
- 該方法建立在基類(FormRequest)基礎之上
- 方法提交時增加類似 token 或者 method 這樣的欄位
_scene
標記場景,當然你也可以不標記,因為他支援預設的。 - 預設場景會把 當前 路由名稱 當做驗證場景名稱,當 request 出現了
_scene
時才會被替換 - 匹配子類
scene
場景陣列 返回特定的 驗證規則rule
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
class Base extends FormRequest
{
/**
* 驗證場景
*
* @var string
*/
public $scene = [];
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Create the default validator instance.
*
* @param \Illuminate\Contracts\Validation\Factory $factory
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function createDefaultValidator(ValidationFactory $factory)
{
return $factory->make(
$this->validationData(), $this->getSceneRules(),
$this->messages(), $this->attributes()
);
}
/**
* 獲取場景驗證規則
*
* @return array
*/
protected function getSceneRules()
{
return $this->handleScene($this->container->call([$this, 'rules']));
}
/***
* 基於路由名稱的場景驗證
*
* @param array $rule
* @return array
*/
public function handleScene(array $rule)
{
$arr = [];
foreach (($scene = $this->scene[$this->getSceneName()] ?? []) as $item){
if( isset($rule[$item])){
$arr[$item] = $rule[$item];
}
}
return $arr ?: $rule;
}
/**
* 獲取場景名稱
*
* @return string
*/
public function getSceneName()
{
return $this->input('_scene', $this->route()->getName());
}
/**
* Get data to be validated from the request.
*
* @return array
*/
public function validationData()
{
return $this->all();
}
}
<?php
// +----------------------------------------------------------------------
// | Do what we can do
// +----------------------------------------------------------------------
// | Date : 2019/12/10 - 4:46 PM
// +----------------------------------------------------------------------
// | Author: seebyyu <seebyyu@gmail.com> :)
// +----------------------------------------------------------------------
namespace App\Http\Requests;
class RoleRequest extends Base
{
public $scene = [
'user.role.update' => ['id', 'name', 'status'],
'user.role.store' => ['name', 'status'],
'state' => ['status']
];
public function rules()
{
return [
'id' => 'required',
'name' => 'required',
'status' => 'required',
];
}
public function messages()
{
return [
'id.required' => '請選擇角色',
'name.required' => '請填寫角色名稱',
'status.required' => '請選擇啟用狀態',
];
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結