我正在尝试为拉拉维尔(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;
...
...
}
}