【问题标题】:Laravel validators: prevent submit 2 parameters togetherLaravel 验证器:防止同时提交 2 个参数
【发布时间】:2020-08-10 17:14:05
【问题描述】:

如何防止出现required_without_all验证器中存在的2个参数,例如:

    return [
        'user' => 'required_without_all:customer,public',
        'customer' => 'required_without_all:user,public',
        'public' => 'required_without_all:user,customer',

    ];

如何防止用户从上面一起提交 2 个密钥,例如:

http://127.0.0.1:8000/app/groups-statistics?user=10&customer=10

这些是允许的请求:

http://127.0.0.1:8000/app/groups-statistics?user=10
http://127.0.0.1:8000/app/groups-statistics?customer=10
http://127.0.0.1:8000/app/groups-statistics?public=true

不允许:

http://127.0.0.1:8000/app/groups-statistics?pubilc=true&customer=10
http://127.0.0.1:8000/app/groups-statistics?user=10&customer=10
http://127.0.0.1:8000/app/groups-statistics?public=10&customer=10

【问题讨论】:

  • 你需要一个自定义的Rule
  • 为什么不直接从 url 中获取第一个参数,并进行必要的验证。

标签: laravel validation laravel-5 laravel-validation


【解决方案1】:

您可以使用验证器扩展来制作自己的验证器:

在AppServiceProvider's 中输入此代码:(或在任何提供者中)

public function boot(){
  Validator::extend('present_only_one_from', function ($attribute, $value, $params, $validator) {
      // $params = [user,customer,public]

      $data = array_keys(array_filter($validator->getData())); // or you can write request()->all()
      // $data = [user,customer] or [user,customer,public] or [user] ...

      $intersect = array_intersect($data, $params); // returns matches of received and in validation rules


      // $intersect [user,customer] && [user,customer,public] => [user,customer] => invalid
      // $intersect [user] && [user,customer,public] => [user] => ($intersect[0] !== $attribute) => valid
      // $intersect [customer] && [user,customer,public] => [customer] => ($intersect[0] !== $attribute) => invalid
      if (count($intersect) != 1 && $intersect[0] !== $attribute) return false;

      return true;
  });
}

自定义验证器闭包接收四个参数:被验证的 $attribute 的名称、属性的 $value、传递给规则的 $parameters 数组以及 Validator 实例。

然后在任何控制器中你都可以使用这个规则:

$validator = Validator::make($request->request->all(), [
    'user' => 'present_only_one_from:user,customer,public',
    'customer' => 'present_only_one_from:user,customer,public',
    'public' => 'present_only_one_from:user,customer,public',
]);

希望对你有帮助

【讨论】:

    【解决方案2】:

    您不能使用 Laravel 验证器来处理 URL 查询字符串,而必须使用中间件。

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class ValidateQueryString
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            if ($public = $request->query('public')) {
                if ($customer = $request->query('customer')) {
                    //Here both exist, handle your logic error
                }
            }
    
            return $next($request);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-19
      • 2018-11-04
      • 2017-03-31
      相关资源
      最近更新 更多