我想知道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
答案 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
,并将其转发到dispatchToQueue
或dispatchNow
。如果您希望覆盖默认行为,可以使用您的命令直接调用其中任何一种方法而不是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
当时还没有。但正如我所看到的那样,乔布斯就像命令一样,但它们排队等候,可以派遣。 (正如您在这些示例中看到的那样,这些命令实现了您提到的接口SelfHandling
和ShouldBeQueued
)。
我认为自己是一位经验丰富的Laravel开发者,但Commands
和Jobs
中的这些变化很难理解。
编辑: 来自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中保持不变