【问题标题】:Laravel - Validate inside Controller without make CustomRequestLaravel - 在控制器内部验证而不进行 CustomRequest
【发布时间】:2021-05-01 10:32:55
【问题描述】:

我想验证我通过路由传递给控制器​​的 get 参数。

api/路由

get /order/{id} -> OrderController::order

public function order($id) {
 // validation here (rules= require,between 1 and 1000)
  return Order::find($id);
}
  1. 如何在不创建单独的请求类的情况下在控制器内部进行验证?
  2. 我必须导入哪个验证类? (这个:Illuminate\Support\Facades\Validator ?)
  3. 这是一个好的或常见的解决方案吗?

【问题讨论】:

  • 您可以使用常规请求本身进行验证...laravel.com/docs/8.x/… ...或者,您可以手动创建它们laravel.com/docs/8.x/validation#manually-creating-validators
  • 两种解决方案都是一个很好的解决方案,我喜欢自定义请求类以使控制器功能更短。正如 Lagbox 所说,它不需要包含一个类。
  • @lagbox 嘿!是的,当我验证我的请求时,这将起作用。但请查看我的订单功能的参数列表。我从 GET 路由中获取 $id 。还是我错了?
  • 路由参数不是输入的一部分...因此您必须将其合并到输入中才能使用$request->validate(....),或者在您定义数据的地方进行手动验证已验证...尽管您是否需要验证该路由参数?

标签: php laravel validation


【解决方案1】:

正如@lagbox 已经写的那样,您可以在 Laravel 文档中检查您的所有问题。

控制器内部的验证

use Illuminate\Http\Request;

class MyController extends Controller
{
    public function order(Request $request, int $id)
    {
      $validated = $this->validate([
          // .. put your fields and rules here
      ]);
    }
}

如果您的控制器扩展了 base controller,每个 Laravel 安装都附带该 base controller,您可以通过 $this->validate 直接访问验证器。

通过注入 $request,您可以访问发送 (POSTed) 到您的服务器的字段。

这是否是一个好的解决方案在很大程度上取决于项目规模和其他因素。这绝对是一个很好的解决方案。如果您的项目增长并且您需要在不同的地方有相同的验证逻辑,您可以再次考虑额外的Form Request Validation

将某些规则应用于路由参数,f。前任。 id,你可以使用Regular Expression Constraints

请求数据的进一步处理

我个人会将验证留在控制器(或表单请求类)中。 如果请求数据有任何问题,那么它应该在那里失败并且不会继续服务类。

您可以说这是一种fail fast 方法。如果您的请求项可能有错误(无效),为什么要在代码中移动越来越多?

【讨论】:

  • 控制器助手validate不幸只接受一个请求,如果它也接受一个数据数组会很好
  • @codedge 听起来不错!还有一个问题。我从我的 OrderController 将 Request 和 $id 传递给我的 OrderService。要访问验证功能,我必须使用控制器扩展我的 OrderService,对吗?我的问题:这是一个优雅的解决方案还是你会做一些不同的事情?
  • @MaikLowrey 我更新了我的帖子。对我来说,将其转移到您的服务中是没有意义的。只是个人笔记,不知道您的所有项目细节。
【解决方案2】:

$id 始终存在,因此 required 验证始终通过。 所以你只需要检查between 1 and 1000 条件。 我认为在路由中使用regex constraints 是个好主意。

Route::get('/order/{id}','OrderController@order')
    ->where(['id'=> '1000|^[1-9]{0,2}[1-9]$']);

如果id 小于 1 或大于 1000 或任何其他随机字符串,它将不匹配路由,如果也没有任何其他匹配路由,则会给出 404 错误。

如果你真的想验证控制器中的路由参数,你可以使用这个:

$validator = \Illuminate\Support\Facades\Validator::make(['id' => $id],
    [
        'id' => 'required|integer|between:1,1000'
    ]
);
$validator->validate();

【讨论】:

  • 很酷的回答!我实现了它,如果我尝试传递一个超过 1000 的 id,laravel 会将我重定向到我的索引路由/(起始页)。为什么我没有从验证中得到任何响应,比如数字不在 1 到 1000 之间?
  • 我发现了 api 调用!我必须将我的请求标头 Accept = application/json.然后我变成了一个带有错误消息的json。但如果我尝试通过网络路由,我不会收到错误消息。
  • @MaikLowrey 因为验证异常会导致重定向“返回”(如果它无法确定“返回”是什么,则默认为/)并带有错误和输入(当不告诉服务器您接受 JSON),因此从您重定向到的路由返回的视图必须处理显示任何错误消息......当您说您接受 JSON 时,您只会得到 JSON
猜你喜欢
  • 1970-01-01
  • 2023-03-22
  • 2021-12-26
  • 2011-03-14
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
相关资源
最近更新 更多