Laravel命令和工作

时间:2015-08-19 12:11:44

标签: laravel laravel-5 jobs laravel-5.1

我想知道Laravel 5.1中不同类似命令的类之间有什么区别。据我所知,Laravel 5.1有以下几种可供选择:

  • 控制台命令(artisan make:console
  • 命令(artisan make:command
    • 处理程序(artisan make::command --handler
  • 工作(artisan make:job

我直接从4.2到5.1,所以我不知道4.2和5.1之间发生了什么,但我被告知中间的(只是命令)基本上不是真的再次使用 - 他们从排队的工作变为5.0中的'命令',但Laravel自从决定反对这一点,他们只是为了兼容性。但是,我不是100%在这一点,所以澄清将是赞赏。

我的具体用例是我想要一个地方放置一个自包含的“可运行”任务。例如,某些东西将从给定目录中删除超过5天的文件(但它可以执行任何操作)。

起初这听起来像是一个控制台命令 - 我希望能够从artisan开始运行它。但我可能也希望它按计划进行(很棒,artisan schedule:run运行控制台命令)。但我可能也想从代码中异步执行它。控制台命令可以同步Artisan::call()一起运行,但对于异步,这是(我认为)队列进入的地方,它突然变成了工作。

好的,我们有一份工作。我们现在可以从代码中将它添加到队列中,但是我们如何将它作为工匠命令(同步)执行?我可以创建一个瘦控制台命令并在其中添加DispatchesJobs特征(或其中的代码),然后分派作业吗?作业是否总是必须排队,或者我们是否可以同步执行作业(理想情况下,输出到控制台命令的输出?)同样的问题是按计划运行它 - 我应该创建这个控制台命令并将其添加到调度程序,或者我可以让调度程序直接运行该作业吗?

最后,我们的'命令'不是控制台命令,也不是工作。正如我之前所说的那样,人们告诉我这些只是来自Laravel 5.0的代码更改(有点)还原。但是artisan make命令对他们来说仍然存在,所以他们不能那个死了。此外,处理自我处理命令(默认情况下,附带handle方法)和“需要”处理程序类(运行artisan make:command --handler)的处理是什么?你如何实际执行这些?手动使用(new App\Command\SomeCommand)->handle();(new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand),还是有一些我不知道的隐藏系统(也许可以使用作业/队列调度程序调度它们)?你也可以创建'排队'命令artisan make::command --queued,那么这些命令有何不同呢?

我想我的问题归结为以下几点:

  • 它们之间真正的(语义功能)区别是什么?
  • “运行”它们的正确方法是什么?
  • 哪种方式最适合我需要运行的通常独立的代码,以我认为合适的方式运行?

我在文档中找到了有关如何使用队列和创建控制台命令的信息,但没有说明何时在命令类和处理程序上使用它们或确实是什么。

相关但不完全相同(也是,没有答案):Laravel 5.1 commands and jobs

3 个答案:

答案 0 :(得分:27)

控制台命令

Laravel有控制台"命令"一段时间它们基本上没有变化,并且像往常一样工作。简单来说,它们相当于命令行的路径 - 应用程序的入口点。它们与...没有任何关系。

命令总线

Laravel 5.0引入了Command Bus模式的实现 - 命令总线命令。 (我相信这些被重命名为Jobs,因为它们与CLI命令之间产生了混淆)。

一个命令总线作为两个部分 - 一个表示要执行的命令的对象,它需要的任何和所有数据(作业),以及一个执行命令的类(处理程序)。

处理程序

在laravel中,您可以将作业声明为自我处理 - 也就是说,它本身就有一个句柄方法。

如果要注册命令处理程序,可以在服务提供者中调用以下内容:

app('Illuminate\Bus\Dispatcher')->maps(['Job' => 'Handler']);

其中Job是作业的类名,Handler是处理程序的类名。

laravel 5.0中的处理程序目录是一种隐式声明这些关系的方式(即命令文件夹中的EmailCommand在处理程序文件夹中会有EmailCommandHandler

调度命令

您可以使用以下命令发送命令。

app('Illuminate\Bus\Dispatcher')->dispatch(new EmailPersonCommand('email@you.com', $otherdata));

队列

默认情况下,作业会在调用(或调度)后立即运行。将它们设置为ShouldQueue将始终在分派时将它们传递给队列。

如果您希望有时同步运行它们,而在其他时间异步运行它们,则可以在希望它们排队时调用$dispatcher->dispatchToQueue($job)。当您将ShouldQueue作业传递给->dispatch()时,这就是内部发生的一切。

编辑:排队(或不排队)

我刚看了一下调度员。 dispatch方法检查命令是否为ShouldQueue,并将其转发到dispatchToQueuedispatchNow。如果您希望覆盖默认行为,可以使用您的命令直接调用其中任何一种方法而不是dispatch

所以在你的情况下,取决于"默认"你的工作行为是(通常是排队吗?): - 拥有ShouldQueue,并在CLI命令中使用dispatchNow。 - 没有ShouldQueue,并使用您在代码中调用它的dispatchToQueue

从它的声音来看,我做前者。

答案 1 :(得分:19)

我看到那些"对象"像这样:(我在我的一个项目中添加了一些代码示例)

控制台

我想从命令行执行的操作(正如您在示例中提到的"删除早于x&#34的文件;)。但问题是,您可以将其业务逻辑提取为命令

Example:一个控制台命令,用于触发从Imgur获取图像的命令。类FetchImages包含获取图像的实际业务逻辑。

命令

包含实际逻辑的类。您还应该能够使用app()->make(Command::class)->handle()从您的应用程序中调用此命令。

Example:示例1中提到的命令。包含对Imgur执行实际API调用并处理返回数据的逻辑。

工作

我用Laravel 5.0制作了这个应用程序,所以jobs当时还没有。但正如我所看到的那样,乔布斯就像命令一样,但它们排队等候,可以派遣。 (正如您在这些示例中看到的那样,这些命令实现了您提到的接口SelfHandlingShouldBeQueued)。

我认为自己是一位经验丰富的Laravel开发者,但CommandsJobs中的这些变化很难理解。

编辑: 来自Laravel Docs:

  

app / Commands目录已重命名为app / Jobs。但是,您不需要将所有命令移动到新位置,并且可以继续使用make:command和handler:命令Artisan命令来生成类。

     

同样,app / Handlers目录已重命名为app / Listeners,现在只包含事件侦听器。但是,您不需要移动或重命名现有的命令和事件处理程序,并且可以继续使用handler:event命令来生成事件处理程序。

     

通过提供Laravel 5.0文件夹结构的向后兼容性,您可以将应用程序升级到Laravel 5.1,并在方便您或您的团队时将您的事件和命令慢慢升级到新位置。

答案 2 :(得分:2)

只是对实际答案的补充。

Laravel中的作业> = 5.1是Laravel 5.0中的命令总线

由于Console\Commands(从控制台运行的命令)与应用程序任务的Command Bus(包含Commands)之间的混淆,这只是命名更改。

你不应该混淆:

  • Command Bus:用于“封装您的应用程序的任务”(来自laravel 5.0 doc),现在已重命名为Jobs
  • Console\Commands:用于“Artraan [...] Laravel附带的命令行界面”(来自laravel 5.1 docs),自从4.x以来在Laravel中保持不变