Laravel 验证器以及验证场景的使用
让你代码看起来更简洁
$data = $request->input();
$validator = Validator::make(
$data,
[
'account' => 'required:exists:admin_user',
'password' => 'required',
],
[
'account.required' => '账号不能为空',
'account.exists' => '账号或密码错误',
'password' => '密码不能为空'
]
);
$vali = $validator->fails();
if($vali) return $this->backData(0,'err',$validator->getMessageBag()->first());
这样的写法容易造成代码冗余太多。
1、首先创建一个基础类
php artisan make:request BaseRequest
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
class BaseRequest extends FormRequest
{
protected function failedValidation(Validator $validator) {
$msg = $validator->getMessageBag()->first();
throw new HttpResponseException(response()->json(['code'=>'500','msg'=>$msg,'data'=>''], 422));
}
}
2、在 app\Providers\AppServiceProvider.php boot 下面添加
Route::macro('scene',function ($scene=null){
$action = Route::getAction();
$action['_scene'] = $scene;
Route::setAction($action);
});
3、创建一个验证类
<?php
namespace App\Http\Requests;
trait SceneValidator
{
protected $scene = null;
protected $autoValidate = true;
protected $onlyRule=[];
public function validateResolved()
{
if(method_exists($this,'autoValidate')){
$this->autoValidate = $this->container->call([$this, 'autoValidate']);
}
if ($this->autoValidate) {
$this->handleValidate();
}
}
protected function handleValidate()
{
$this->prepareForValidation();
if (! $this->passesAuthorization()) {
$this->failedAuthorization();
}
$instance = $this->getValidatorInstance();
if ($instance->fails()) {
$this->failedValidation($instance);
}
}
public function validator($factory)
{
return $factory->make($this->validationData(), $this->getRules(), $this->messages(), $this->attributes());
}
public function validate($scene='')
{
if(!$this->autoValidate){
if(is_array($scene)){
$this->onlyRule = $scene;
}else{
$this->scene = $scene;
}
$this->handleValidate();
}
}
protected function getRules()
{
return $this->handleScene($this->container->call([$this, 'rules']));
}
protected function handleScene(array $rule)
{
if($this->onlyRule){
return $this->handleRule($this->onlyRule,$rule);
}
$sceneName = $this->getSceneName();
if($sceneName && method_exists($this,'scene')){
$scene = $this->container->call([$this, 'scene']);
if(array_key_exists($sceneName,$scene)) {
return $this->handleRule($scene[$sceneName],$rule);
}
}
return $rule;
}
private function handleRule(array $sceneRule,array $rule)
{
$rules = [];
foreach ($sceneRule as $key => $value) {
if (is_numeric($key) && array_key_exists($value,$rule)) {
$rules[$value] = $rule[$value];
} else {
$rules[$key] = $value;
}
}
return $rules;
}
protected function getSceneName()
{
return is_null($this->scene) ? $this->route()->getAction('_scene') : $this->scene;
}
}
4、创建自己的验证类 代码如下
<?php
namespace App\Http\Requests;
class StorePostRequest extends BaseRequest
{
use SceneValidator;
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
public function scene()
{
return [
'add' => [
'title' ,
'body'
],
'edit' => ['body'],
];
}
}
5、来看看我们路由是如何写的
Route::get('/posts/popular', [\App\Http\Controllers\PostController::class, 'popular'])->scene('edit');
6、我们只需要爸验证类注入到控制器就OK了
public function popular(StorePostRequest $request)
{
$posts = $this->postRepo->trending(10);
if ($posts) {
dd($posts->toArray());
}
}
7、接下来看一下结果 是不是方便了很多,快去试试吧!!!!!!
|