Laravel:如果传递未知字段,如何使更新无效

时间:2019-06-06 14:08:47

标签: php laravel validation

我有一个自定义验证器:

    $validator = Validator::make($request->all(), [
        'name' => 'sometimes|unique:stock.containers|max:255',
    ]);

如果我想抛出一个错误:

 PUT:localhost/my/model?description=foobar

因为在这种情况下,我只想接受name。然后,我将确保我的$validator->valid()仅包含接受的字段。

这是我的控制器:

class ContainerController extends Controller
{
    public function update($id, Request $request) {
        $container = Container::find($id);

        $rules = ['name' => 'max:255'];

        $validator = Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);  //i'm not getting any
        }

        $container->update($validator->valid());
    }
}

根据上述请求,我到达了$container->update。我想将该字段限制为我的规则中提到的内容。

3 个答案:

答案 0 :(得分:2)

您可以使用控制器的内置validate方法,而不用创建Validator的新实例。

public function update($id, Request $request) {
    $valid = $this->validate($request, [
        'name' => 'max:255',
    ]);

    dd($valid);
}

因此,即使有人提交了规则中未包括的其他参数,也不会将其包括在内。

在我们的情况下,如果您按照上述说明执行curl请求,$valid将返回一个空数组。

然后您可以检查数组是否为空:

if (empty($valid)) {
    // Do what you want
}

旁注

我注意到您正在使用Container::find($id);,但是您也可以在路由文件中使用内置的模型绑定:

Route::put('your-path/{container}', 'ContainerController@update');

代替

Route::put('your-path/{id}', 'ContainerController@update');

然后将哪个允许在您的控制器中使用:

public function update(Container $container, Request $request)
{
    // $container would be the Container instance already
}

更新

如果您仍然想创建一个新的Validator实例,则可以这样做:

$validator = \Validator::make($request->all(), $rules);


if ($validator->fails()) {
    // ...
}

if (! $valid = $validator->validated()) {
    // Nothing has been validated
}

基本上,您应该使用$validator->validated()而不是$validator->valid()来仅从规则中检索字段。

答案 1 :(得分:1)

您可以做的是发出一种请求类型,该请求过滤掉不需要的参数,因此您可以将其传递到控制器中,例如:private function myfunction(MyCustomRequest $request),这样,当它到达验证器时,无效的参数已被删除。

在您的MyCustomRequest中,您可以列出有效参数,如下所示:

 $validParameters = ["name"]; // add as many as you need

因此,您现在要检查请求中的内容,您可以使用$request->all()查看该内容。您可以遍历有效的参数,并且只返回与自定义列表匹配的请求值。

 $requestData = $request->all();

 $goodRequestData = [];

 foreach ($validParameters as $validParameter) {
      if (array_key_exists($validParameter, $requestData) {
           $goodRequestData[] = $requestData[$validParameter];
      }
 }

 return $goodRequestData;

您可以在以下Laravel文档中了解有关自定义请求的更多信息:https://laravel.com/docs/5.8/validation#creating-form-requests

答案 2 :(得分:1)

您可以简单地使用->only()方法:

class ContainerController extends Controller
{
    public function update($id, Request $request) {
        $container = Container::find($id);

        $rules = ['name' => 'max:255'];

        $validator = Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);  //i'm not getting any
        }

        $container->update($request->only(['name']));
    }
}

从文档中

  

唯一的方法返回您请求的所有键/值对;但是,它不会返回请求中不存在的键/值对。