在laravel中实现Command处理程序的问题

时间:2015-04-07 11:28:11

标签: php laravel laravel-5

我为我工作的办公室实施人力资源系统的一个小组件。我目前正致力于允许用户申请假期。我尽我所能使用命令处理程序(并且希望事件也是如此),因为我的控制器总是很臃肿。

我想在我的应用程序中执行以下操作:

首先,用户点击表单上的提交到"创建新请求"例如,假期。这应该转到RequestController上的store()方法并触发一个自处理命令,即CreateRequestCommand。然后,此命令将存储用户在数据库中发出的请求,然后继续执行我还没有完成的功能。

在实施上述内容时,我遇到了两个问题:

首先,我的表单有一个文件上传。如你所知,如果我dd()我的控制器中的文件,我将看到我可以用来上传它的文件属性。但是,如果我在CreateRequestCommand的handle()函数中dd()它显示null。所以,我对应该在哪里执行上传逻辑感到困惑?

其次,我的表单有9个字段,几乎与我在数据库中存储的字段相匹配,但user_id除外。所以通常我会做什么,而且我知道这被认为是后向练习,因此为什么我尝试使用命令,从表单中获取所有输入然后将其全部放在create()函数中将模型存储在DB中的模型。现在我已经将这个逻辑提取到命令,并从laracasts和PurchasePodcastCommand(或其他任何东西)的文档中查看Taylor Otwell的示例,我知道我需要将所有相关数据放入Command的构造函数,这意味着我在构造函数中有9个变量。现在请原谅我的无知,但在构造函数中有9个变量看起来不对,所以我问自己现在在这里 - 我这样做了吗?以下是我在上面提到的类中的一些相关代码。

应用\ HTTP \控制器\ RequestController.php

public function store(Requests\CreateRequestRequest $request)
{
    $this->dispatchFrom(CreateRequestCommand::class, $request);
}

应用\命令\ 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,
        ]);
    }

}

非常感谢能提供任何建议的任何人。如果您需要查看更多代码或其他任何内容,我乐意与您分享。

1 个答案:

答案 0 :(得分:2)

在Command构造函数中有九个变量完全没有错。命令对象是处理程序的DTO(数据传输对象),因此这不仅是完全可以接受的,而且也是推荐的方式。命令对象负责确保处理程序收到所需的$ command-> vars所以是的,它们应该在构造函数中。

更新: 抱歉忘记了关于文件上传的其他问题:

要在FormRequestObject中处理上传的文件,请使用$request->file('inputname')代替$request->input('name')

更新: 在回复关于具有单独的命令处理程序对象的注释时,

在Laravel 5中,你可以拥有一个CommandObject,它可以自己处理命令,也可以有一个单独的处理程序。

创建自我处理命令对象: php artisan make:command NameOfCommand

这将在app / Commands中创建一个命令,它将具有构造函数()和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));