在 laravel 中实现命令处理程序时出现问题
Problems implementing a Command handler in laravel
我正在为我工作的办公室的 HR 系统实施一个小组件。我目前正在努力让用户申请休假。我正在尽最大努力使用命令处理程序(希望也是事件),因为我的控制器总是非常臃肿。
我想在我的应用程序中执行以下操作:
首先,用户点击表单提交到 "create new request" 例如假期。这应该转到 RequestController 上的 store() 方法并触发一个自处理命令,即 CreateRequestCommand。然后,此命令会将用户发出的请求存储在数据库中,然后继续执行我尚未完成的功能。
我在实施上述内容时遇到了两个问题:
首先,我的表格有一个文件上传。如您所知,如果我在我的控制器中使用 dd() 文件,我将看到可用于上传它的文件属性。但是,如果我在 CreateRequestCommand 的 handle() 函数中 dd() 它,它显示为 null。所以,我对应该在哪里执行上传逻辑感到困惑?
其次,我的表单有 9 个字段,它们与我在数据库中存储的内容非常匹配,user_id 除外。所以通常我会做的,我知道这被认为是回溯练习,因此我尝试使用命令的原因是从表单中获取所有输入,然后将其全部放入模型的 create() 函数中进行存储它在数据库中。现在我已经将该逻辑提取到命令中,并通过在 laracasts 和 PurchasePodcastCommand 的文档(或其他任何内容)中查看 Taylor Otwell 的示例,我明白我需要将所有相关数据放在命令的构造函数中,这意味着我在构造函数中有 9 个变量。现在原谅我的无知,但是在构造函数中有 9 个变量看起来是错误的,所以我现在问自己 - 我这样做对吗?下面是我在上面提到的 类 中的一些相关代码。
app\Http\Controllers\RequestController.php
public function store(Requests\CreateRequestRequest $request)
{
$this->dispatchFrom(CreateRequestCommand::class, $request);
}
app\Commands\CreateRequestCommand.php
class CreateRequestCommand extends Command implements SelfHandling {
/**
* Values from request
* @var mixed
*/
protected $requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct($requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover)
{
$this->requestType = $requestType;
$this->attachment = $attachment;
$this->manager = $manager;
$this->noOfDays = $noOfDays;
$this->dateFrom = $dateFrom;
$this->dateTo = $dateTo;
$this->location = $location;
$this->contactNumber = $contactNumber;
$this->cover = $cover;
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
// store to db here
dd([
'requestType' => $this->requestType,
'attachment' => $this->attachment,
'manager' => $this->manager,
'noOfDays' => $this->noOfDays,
'dateFrom' => $this->dateFrom,
'dateTo' => $this->dateTo,
'location' => $this->location,
'contactNumber' => $this->contactNumber,
'cover' => $this->cover,
]);
}
}
非常感谢任何可以提供任何建议的人。如果您需要查看更多代码或任何内容,我很乐意与您分享。
在 Command 构造函数中有九个变量并没有错。命令对象是处理程序的 DTO(数据传输对象),因此这不仅是完全可以接受的,而且也是推荐的方式。命令对象负责确保处理程序收到所需的 $command->vars 所以是的,它们应该在构造函数中。
更新:
抱歉忘记了关于文件上传的其他问题:
要在您的 FormRequestObject 中处理上传的文件,请使用 $request->file('inputname')
而不是 $request->input('name')
更新:
在回复关于拥有一个单独的命令处理程序对象的评论时,
在 Laravel 5 中,您可以拥有一个自己处理命令的 CommandObject,也可以拥有一个单独的处理程序。
创建自处理命令对象:
php artisan make:command NameOfCommand
这将在 app/Commands 中创建一个命令,它将有一个 constructor() 和一个 handle() 方法。所有命令参数都应在构造函数中启动。
要使用单独的处理程序轻松创建命令,您只需使用:
php artisan make:command NameOfCommand --handler
这将在 app/commands 中创建一个仅包含构造函数的命令对象,并且还将在 app/Handlers/Commands
中创建一个命令处理程序
您应该在 Command 对象的构造函数中初始化您的命令属性。
命令处理程序将有一个 handle() 方法,其中 CommandObject 作为参数传递。这样你就可以使用处理程序的构造函数来注入其他依赖项,例如处理命令可能需要的存储库。
在命令处理程序 handle() 方法中,您只需键入 $command->attachment
等内容即可获取命令属性...
这应该可以回答您的所有问题:)
更新:
如下更改您的控制器方法:
// assign the request properties to variables - note the file is handled differently.
$requestType = $request->get('requestType');
$attachment = $request->file('attachment');
$manager = $request->get('manager');
$noOfDays = $request->get('noOfDays');
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
$location = $request->get('location');
$contactNumber = $request->get('contactNumber');
$cover = $request->get('cover');
// dispatch the command
return $this->dispatch(new CreateRequestCommand($requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover));
我正在为我工作的办公室的 HR 系统实施一个小组件。我目前正在努力让用户申请休假。我正在尽最大努力使用命令处理程序(希望也是事件),因为我的控制器总是非常臃肿。
我想在我的应用程序中执行以下操作:
首先,用户点击表单提交到 "create new request" 例如假期。这应该转到 RequestController 上的 store() 方法并触发一个自处理命令,即 CreateRequestCommand。然后,此命令会将用户发出的请求存储在数据库中,然后继续执行我尚未完成的功能。
我在实施上述内容时遇到了两个问题:
首先,我的表格有一个文件上传。如您所知,如果我在我的控制器中使用 dd() 文件,我将看到可用于上传它的文件属性。但是,如果我在 CreateRequestCommand 的 handle() 函数中 dd() 它,它显示为 null。所以,我对应该在哪里执行上传逻辑感到困惑?
其次,我的表单有 9 个字段,它们与我在数据库中存储的内容非常匹配,user_id 除外。所以通常我会做的,我知道这被认为是回溯练习,因此我尝试使用命令的原因是从表单中获取所有输入,然后将其全部放入模型的 create() 函数中进行存储它在数据库中。现在我已经将该逻辑提取到命令中,并通过在 laracasts 和 PurchasePodcastCommand 的文档(或其他任何内容)中查看 Taylor Otwell 的示例,我明白我需要将所有相关数据放在命令的构造函数中,这意味着我在构造函数中有 9 个变量。现在原谅我的无知,但是在构造函数中有 9 个变量看起来是错误的,所以我现在问自己 - 我这样做对吗?下面是我在上面提到的 类 中的一些相关代码。
app\Http\Controllers\RequestController.php
public function store(Requests\CreateRequestRequest $request)
{
$this->dispatchFrom(CreateRequestCommand::class, $request);
}
app\Commands\CreateRequestCommand.php
class CreateRequestCommand extends Command implements SelfHandling {
/**
* Values from request
* @var mixed
*/
protected $requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct($requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover)
{
$this->requestType = $requestType;
$this->attachment = $attachment;
$this->manager = $manager;
$this->noOfDays = $noOfDays;
$this->dateFrom = $dateFrom;
$this->dateTo = $dateTo;
$this->location = $location;
$this->contactNumber = $contactNumber;
$this->cover = $cover;
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
// store to db here
dd([
'requestType' => $this->requestType,
'attachment' => $this->attachment,
'manager' => $this->manager,
'noOfDays' => $this->noOfDays,
'dateFrom' => $this->dateFrom,
'dateTo' => $this->dateTo,
'location' => $this->location,
'contactNumber' => $this->contactNumber,
'cover' => $this->cover,
]);
}
}
非常感谢任何可以提供任何建议的人。如果您需要查看更多代码或任何内容,我很乐意与您分享。
在 Command 构造函数中有九个变量并没有错。命令对象是处理程序的 DTO(数据传输对象),因此这不仅是完全可以接受的,而且也是推荐的方式。命令对象负责确保处理程序收到所需的 $command->vars 所以是的,它们应该在构造函数中。
更新: 抱歉忘记了关于文件上传的其他问题:
要在您的 FormRequestObject 中处理上传的文件,请使用 $request->file('inputname')
而不是 $request->input('name')
更新: 在回复关于拥有一个单独的命令处理程序对象的评论时,
在 Laravel 5 中,您可以拥有一个自己处理命令的 CommandObject,也可以拥有一个单独的处理程序。
创建自处理命令对象:
php artisan make:command NameOfCommand
这将在 app/Commands 中创建一个命令,它将有一个 constructor() 和一个 handle() 方法。所有命令参数都应在构造函数中启动。
要使用单独的处理程序轻松创建命令,您只需使用:
php artisan make:command NameOfCommand --handler
这将在 app/commands 中创建一个仅包含构造函数的命令对象,并且还将在 app/Handlers/Commands
中创建一个命令处理程序您应该在 Command 对象的构造函数中初始化您的命令属性。
命令处理程序将有一个 handle() 方法,其中 CommandObject 作为参数传递。这样你就可以使用处理程序的构造函数来注入其他依赖项,例如处理命令可能需要的存储库。
在命令处理程序 handle() 方法中,您只需键入 $command->attachment
等内容即可获取命令属性...
这应该可以回答您的所有问题:)
更新:
如下更改您的控制器方法:
// assign the request properties to variables - note the file is handled differently.
$requestType = $request->get('requestType');
$attachment = $request->file('attachment');
$manager = $request->get('manager');
$noOfDays = $request->get('noOfDays');
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
$location = $request->get('location');
$contactNumber = $request->get('contactNumber');
$cover = $request->get('cover');
// dispatch the command
return $this->dispatch(new CreateRequestCommand($requestType, $attachment, $manager, $noOfDays, $dateFrom, $dateTo, $location, $contactNumber, $cover));