Laravel命令和工作

ale*_*ell 30 jobs laravel laravel-5 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();or (new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand),或者是否有一些我不知道的隐藏系统(也许可以使用作业/队列调度程序调度它们)?你也可以创建'排队'命令artisan make::command --queued,那么这些命令有何不同呢?

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

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

我在文档中找到了有关如何使用队列和创建控制台命令的信息,但没有关于何时使用它们或在命令类和处理程序上的任何内容的确切信息.


相关但不完全相同(也没有答案):Laravel 5.1命令和作业

ste*_*tef 29

控制台命令

Laravel已经有一段时间的控制台"命令"了.它们基本没有变化,并且一如既往地工作.简单来说,它们等同于命令行的路径 - 应用程序的入口点.它们与......无关

命令总线

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

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

处理程序

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

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

app('Illuminate\Bus\Dispatcher')->maps(['Job' => 'Handler']);
Run Code Online (Sandbox Code Playgroud)

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

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

调度命令

您可以使用以下命令来分派命令.

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

队列

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

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

编辑:排队(或不排队)

我刚看了一下调度员.该dispatch方法检查命令是否为a ShouldQueue,并将其转发给dispatchToQueuedispatchNow.如果dispatch要覆盖默认行为,可以直接调用这些方法中的任何一种,而不是使用命令.

那么在你的情况下,取决于你的工作的"默认"行为(即它通常会排队吗?): - 拥有它ShouldQueue,并dispatchNow在CLI命令中使用.- 没有它ShouldQueue,并使用dispatchToQueue你在代码中调用它的地方.

从它的声音,我做前者.


ste*_*fel 22

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

安慰

我想从命令行执行的操作(正如您在"删除早于x的文件"中所提到的那样).但问题是,您可以将其业务逻辑提取到命令中.

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

命令

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

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

工作

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


我认为自己是一位经验丰富的Laravel开发人员,但这些变化Commands并且Jobs很难理解.

编辑:来自Laravel文档:

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

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

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