我正在尝试制作一个crud控制器库,从我扩展它并设置模型库然后我有一些基本的crud方法。我得到了所有动态的工作。但我不能创建一个动态请求类型,为了验证它,我有ChannelRequest,它的工作正常如下,但我希望它是动态的:
这是我的CrudController类(我将扩展并设置模型):
public function store(ChannelRequest $request)
{
$this->save($request); // this method get the model instantiated in parent class and save the inputs
return redirect('admin/' . $this->plural);
}
在上面这个例子中我对依赖注入的请求类型进行了硬编码,然后验证,但我想动态更改请求类型,如下所示:
// i know it not being work
public function store($this->model .'Request' $request)
{
$this->save($request);
return redirect('admin/' . $this->plural);
}
我试过这个:
public function store()
{
$request = new ChannelRequest();
$request->validate(); //hopping it runs like when dependency injection
$this->save($request);
return redirect('admin/' . $this->plural);
}
这让我误以为:
FatalErrorException in FormRequest.php line 75:
Call to a member function make() on null
in FormRequest.php line 75
at FatalErrorException->__construct() in HandleExceptions.php line 133
at HandleExceptions->fatalExceptionFromError() in HandleExceptions.php line 118
at HandleExceptions->handleShutdown() in HandleExceptions.php line 0
at FormRequest->getValidatorInstance() in ValidatesWhenResolvedTrait.php line 20
at FormRequest->validate() in CrudController.php line 67
答案 0 :(得分:4)
首先,我想强调的是,为每个资源(模型)设置单独的控制器是一种很好的做法,可以防止单独的问题过于混杂。使用动态Request类会破坏显式定义请求类的目的。
然而,为了回答这个问题我能做的最好,我会告诉你如何解决这个问题。此代码未经测试,但概念应该是合理的。
我在这里做的是使用SmartRequest类扩展标准Request类并覆盖__construct
以允许我为给定请求类型的正确请求类运行预加载器。 / p>
这将允许您定义单独的请求类,然后根据SmartRequest::$subRequest
请求参数将它们加载到resourceType
属性中(如果是POST,GET或URL参数,则可以将其加载到App\Http\Requests\SmartRequest
属性中你想修改最后一个代码。)
代码:<?php
use App\Http\Requests\Request;
class SmartRequest extends Request {
/**
* Holds sub request class
* @var Request
*/
protected $subRequest;
/**
* Default constructor
* @param array $query
* @param array $request
* @param array $attributes
* @param array $cookies
* @param array $files
* @param array $server
* @param string|resource $content
*/
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
// make sure standard constructor fires
parent::__construct($query, $request, $attributes, $cookies, $files, $server, $content);
// instantiate the sub request object, we must also pass through all the data for the base
// request since the sub class requires this data.
$this->loadSubRequest($query, $request, $attributes, $cookies, $files, $server, $content);
}
/**
* Default constructor
* @param array $query
* @param array $request
* @param array $attributes
* @param array $cookies
* @param array $files
* @param array $server
* @param string|resource $content
*/
public function loadSubRequest($query, $request, $attributes, $cookies, $files, $server, $content)
{
// get resource type off the request data to generate the class string
$class = $this->getRequestClassName();
$this->subRequest = new $class($query, $request, $attributes, $cookies, $files, $server, $content);
}
/**
* Get the sub class name with namespace
* @return string
*/
public function getRequestClass()
{
return '\<path>\<to\<namespace>\\' . studly_case($this->resourceType) . 'Request';
}
/**
* Returns rules based on subclass, otherwise returns default rules
* @return array
*/
public function rules()
{
// return the default rules if we have no sub class
if (empty($this->subRequest)) return [];
// return the rules given by the sub class
return $this->subRequest()->rules();
}
}
requestType
同样,这不是真正的代码(因为我还没有测试过),但这可能是一种完成请求的方法。这还依赖于在请求上发送了一些标识符(在这种情况下,是ChannelRequest $request
参数),因为您不知道有关请求的任何信息,除了它的发送位置和参数。
尽管如此,我认为这完全违背了此功能的意图。拥有显式请求并在需要它们的方法中明确使用它们要好得多。为什么?自我记录代码。只需在操作中阅读SmartRequest
之类的内容,人们就会知道您所使用的内容。上述内容(SmartRequest
)会导致某种神奇的事情发生,任何其他开发人员在撕开void display(LinkedList *root)
{
if(root->nextNode==NULL)
{
cout<<root->data<<endl;
}
else
{
while(root->nextNode!=NULL)
{
cout<<root->data<<endl;
root=root->nextNode;
}
}
}
课程之前都无法理解。
让我知道这是否令人困惑,或者如果您有任何其他问题我为什么认为这种方法朝着错误的方向迈出了一步。