Laravel 5变量类型提示请求



我正在尝试为拉拉维尔(Laravel)建立一个非常普遍的碎屑,但我陷入了验证。

我有一个宁静的资源控制器,可以处理任何实体的基本操作:

class CrudController extends Controller {
  public function store(StoreRequest $request) {...}
  public function update(UpdateRequest $request) {...}
  ...
}

每个实际实体都有自己的控制器,可以扩展它:

  • ArticleController扩展了CrudController
  • categoryController扩展了CrudController
  • tagcontroller扩展了crudcontroller

因此,当您调用ARTICLECONTROLLER()中的create()方法时,它基本上调用crudcontroller :: create()。

到目前为止一切都很好。现在有了验证问题:

对于文章实体,我将以以下方式定义验证规则:

  • app/http/requests/storearticlerequest.php

  • app/http/requests/updateAtearticLerequest.php

但是,请求类已经在 crudcontroller 中定义了,因此Laravel将使用该类型进行类型拟合,因此已执行的验证将是 StoreRequest 的验证我想要一个, storearticlerequest

如何将这些类传递给 create() update()方法 crudcontroller

不能做:

我不想在 articlecontroller 中重新定义 create()方法每个EntityController都会导致重复的代码。另外,它们将具有不同的参数,这将触发"应与" PHP错误兼容。

已经尝试过:

在CrudController中:

use AppHttpRequestsStoreCRUDRequest as StoreRequest;
use AppHttpRequestsUpdateCRUDRequest as UpdateRequest;
class CrudController extends Controller {
  public function store(StoreRequest $request) {...}
  public function update(UpdateRequest $request) {...}
  ...
}

在articlecontroller中:

use AppHttpRequestsStoreArticleRequest as StoreRequest;
use AppHttpRequestsUpdateArticleRequest as UpdateRequest;
class ArticleController extends CrudController {
  ...
  // the create() and store() methods are no longer defined here
}

但是它不起作用,因为articleController laravel仍然可以从app http requests storecrudrequest运行crudcontroller中定义的验证。

知道我如何实现这一目标?

而不是类型提示,您可以使用resolve()助手来解决FormRequest类。请参阅第33行上的formrequestServiceProvider和Helper Docs

abstract class CrudController extends Controller {
    protected $modelClassName;   # Name of your model class
    protected $storeRequest;     # Name of your store FormRequest class
    protected $updateRequest;    # Name of your update FormRequest class
    public function store(): Model {
        $modelClassName = $this->modelClassName;
        $request = resolve($this->storeRequest);
        $instance = $modelClassName::create($request->validated());
        return $instance;
    }
    public function update($id): Model {
        $modelClassName = $this->modelClassName;
        $instance = $modelClassName::find($id);
        $request = resolve($this->updateRequest);
        $instance->fill($request->validated())->save();
        return $instance;
    }
}

是否有任何理由反对将请求对象传递到构造函数并在运行时注入Laravel?

示例:

<?php
class ArticleController extends CrudController {
    use CreateOperation;
    public function __construct(StoreArticleRequest $storeRequest, UpdateArticleRequest $updateRequest)
    {
        $this->storeRequest  = $storeRequest;
        $this->updateRequest = $updateRequest;
        parent::__construct();
    }
}

trait CreateOperation
{
    /**
     * @var Request
     */
    private $storeRequest;
    public function setStoreRequest(Request $storeRequest): void
    {
        $this->storeRequest = $storeRequest;
    }
    public function storeCrud()   // parameter removed
    {
        $request = $this->storeRequest;
        ...
        ...
    }
}

最新更新