Laravel 命令和作业

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32095167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 17:06:00  来源:igfitidea点击:

Laravel commands and jobs

laravellaravel-5jobslaravel-5.1

提问by alexrussell

I was wondering what the difference is between the different command-like classes in Laravel 5.1. As far as I can tell Laravel 5.1 has the following available:

我想知道 Laravel 5.1 中不同的类似命令的类之间有什么区别。据我所知,Laravel 5.1 具有以下可用功能:

  • Console commands (artisan make:console)
  • Commands (artisan make:command)
    • Handlers (artisan make::command --handler)
  • Jobs (artisan make:job)
  • 控制台命令 ( artisan make:console)
  • 命令 ( artisan make:command)
    • 处理程序 ( artisan make::command --handler)
  • 工作 ( artisan make:job)

I have come straight from 4.2 to 5.1 so I don't know what happened in between 4.2 and 5.1, but I have been told that the middle one (justcommands) are basically not really supposed to be used any more - they are in from when queue-able jobs became 'commands' in 5.0, but Laravel since decided against this, and they're just in for compatibility. However, I'm not 100% on this point, so clarification would be appreciated.

我直接从 4.2 到 5.1,所以我不知道在 4.2 和 5.1 之间发生了什么,但是我被告知中间的(只是命令)基本上不应该再使用了 - 它们来自当可排队的作业在 5.0 中成为“命令”时,但 Laravel 决定反对这一点,它们只是为了兼容性。但是,我不是 100% 在这一点上,所以澄清将不胜感激。

My specific use-case is that I want a place to put a self-contained 'runnable' task. For example, something that will remove files older than 5 days from a given directory (but it could do anything).

我的具体用例是我想要一个地方放置一个独立的“可运行”任务。例如,从给定目录中删除超过 5 天的文件的东西(但它可以做任何事情)。

At first this sounds like a console command - I want to be able to run it from artisan, for a start. But I may also want it on a schedule (great, artisan schedule:runruns console commands). But I may also want to execute it asynchronously from code. Console commands can be run synchronouslywith Artisan::call(), but for asynchronous, this is (I think) where queues come in, and it suddenly has to be a job.

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

Okay so we have a job. We can now add it to a queue from code, but how do we execute it as an artisan command (synchronously)? Can I just create a thin console command and add the DispatchesJobstrait (or the code therein) to it, and then dispatch the job? Does the job always have to go on a queue, or can we make a job execute synchronously (and, ideally, output to the console command's output?) The same question goes for running it on a schedule - am I supposed to create this console command and add that to the scheduler, or can I make the scheduler run the job directly?

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

And finally, we have 'commands' that aren't console commands nor are they jobs. As I said before, people tell me these are just hangers-on from a Laravel 5.0 code change that was (kinda) reverted. But the artisan makecommand still exists for them, so they can't be thatdead. Also, what's the deal with a self handling command (the default, comes with a handlemethod) and one that 'requires' a handler class (run artisan make:command --handler)? How do you actually make these execute? Manually with (new App\Command\SomeCommand)->handle();or (new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand), or is there some hidden system I don't know about (maybe they can be dispatched using the job/queue dispatcher)? Also you can create 'queued' commands artisan make::command --queued, so how do these differ, too?

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

I guess my question boils down to the following:

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

  • What is the real (semantic andfunctional) difference between them all?
  • What is the correct way to 'run' them?
  • Which is best for my purposes of a generally-standalone bit of code that needs to be run, in whatever manner I feel appropriate?
  • 它们之间真正的(语义功能)区别是什么?
  • “运行”它们的正确方法是什么?
  • 对于需要以任何我认为合适的方式运行的通常独立的代码,哪个最适合我的目的?

I found information in the documentation on how to use queues and create console commands, but nothing on exactly when to use them or really anything on command classes and handlers.

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



Related but not exactly the same (also, it's unanswered): Laravel 5.1 commands and jobs

相关但不完全相同(也未回答):Laravel 5.1 命令和作业

采纳答案by stefanzweifel

I see those "objects" like so: (I added some code examples from one of my side projects)

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

Console

安慰

Things I want to execute from the command line (As you mentioned with your example with "Delete Files older than x"). But the thing is, you could extract the business logic of it to a command.

我想从命令行执行的事情(正如您在示例中提到的“删除早于 x 的文件”)。但问题是,您可以将其业务逻辑提取到命令中

Example: A console command with fires a command to fetch images from Imgur. The Class FetchImagescontains the actual business logic of fetching images.

示例:控制台命令触发命令以从 Imgur 获取图像。该类FetchImages包含获取图像的实际业务逻辑。

Command

命令

Class which contains the actual logic. You should also be able to call this command from your application with app()->make(Command::class)->handle().

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

Example: Command mentioned in Example 1. Contains logic which does the actual API calls to Imgur and process returned data.

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

Jobs

工作

I made this app with Laravel 5.0 so jobsweren't a thing back then. But as I see it, Jobs are like commands but they are queued and can be dispatched. (As you may have seen in those examples, those commands implement your mentioned Interfaces SelfHandlingand ShouldBeQueued).

我用 Laravel 5.0 制作了这个应用程序,所以jobs当时还不是什么东西。但在我看来,Jobs 就像命令一样,但它们是排队的并且可以被调度。(正如您在这些示例中所看到的,这些命令实现了您提到的接口SelfHandlingShouldBeQueued)。



I see myself as an experienced Laravel Developer but those changes in Commandsand Jobsare quite difficult to understand.

我把自己看作一个有经验的开发人员Laravel但这些变化CommandsJobs非常难以理解。

EDIT: From the Laravel Docs:

编辑:来自 Laravel 文档:

The app/Commands directory has been renamed to app/Jobs. However, you are not required to move all of your commands to the new location, and you may continue using the make:command and handler:command Artisan commands to generate your classes.

Likewise, the app/Handlers directory has been renamed to app/Listeners and now only contains event listeners. However, you are not required to move or rename your existing command and event handlers, and you may continue to use the handler:event command to generate event handlers.

By providing backwards compatibility for the Laravel 5.0 folder structure, you may upgrade your applications to Laravel 5.1 and slowly upgrade your events and commands to their new locations when it is convenient for you or your team.

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

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

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

回答by stef

Console Commands

控制台命令

Laravel has had console "commands" for some time. They are basically unchanged, and work as they always have. In simple terms, they are the equivalent of routes for the command line - the entry point into the application. They are in no way related to...

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

The Command Bus

命令总线

Laravel 5.0 introduced an implementation of the Command Buspattern - Command Bus Commands. (I believe these were renamed to Jobs because of the resulting confusion between them and CLI Commands).

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

A command bus as two parts - an object that represents a command to be executed, with any and all data it needs (the job), and a class to execute the command (the handler).

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

The Handler

处理程序

In laravel, you can declare a job to be self handling - that is, it has a handle method itself.

在 Laravel 中,您可以将作业声明为自处理——也就是说,它本身有一个 handle 方法。

If you want to register a command handler, you can call the following in a service provider:

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

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

where Job is the class name for the job, and Handler is the class name for the handler.

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

The handlers directory in laravel 5.0 was a way of implicitly declaring those relationships (ie. EmailCommandin the commands folder would have an EmailCommandHandlerin the handlers folder).

laravel 5.0 中的 handlers 目录是一种隐式声明这些关系的方式(即EmailCommand在 commands 文件夹中将EmailCommandHandler在 handlers 文件夹中有一个)。

Dispatching a Command

调度命令

You can use the following to dispatch a command.

您可以使用以下命令来调度命令。

app('Illuminate\Bus\Dispatcher')->dispatch(new EmailPersonCommand('[email protected]', $otherdata));

Queues

队列

Jobs, by default, will run as soon as they are called (or dispatched). Setting them as ShouldQueuewill always pass them to a queue when they are dispatched.

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

If you want to run them synchronously sometimes, and asynchronously other times, you can call $dispatcher->dispatchToQueue($job)when you want them to be queued. This is all that happens internally when you pass a ShouldQueuejob to ->dispatch().

如果您想有时同步运行它们,有时又想异步运行它们,则可以$dispatcher->dispatchToQueue($job)在希望它们排队时调用。当您将ShouldQueue作业传递给->dispatch().

edit: To Queuing (or not)

编辑:排队(或不排队)

I've just had a longer look at the dispatcher. The dispatchmethod checks if the command is a ShouldQueue, and either forwards it to dispatchToQueueor dispatchNow. You can call either of those methods directly instead of dispatchwith your command should you wish to override the default behaviour.

我只是对调度员有更长时间的观察。该dispatch方法检查命令是否为 a ShouldQueue,并将其转发到dispatchToQueuedispatchNow。如果dispatch您希望覆盖默认行为,您可以直接调用这些方法中的任何一个,而不是使用您的命令。

So in your case, depending on what the "default" behaviour of your job is (ie. will it normally be queued?) either: - have it ShouldQueue, and use dispatchNowin the CLI Command. - don't have it ShouldQueue, and use dispatchToQueuewhere you call it in your code.

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

From the sounds of it, i'd do the former.

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

回答by Ifnot

Just an addition to the actual answers.

只是对实际答案的补充。

Jobs in Laravel >= 5.1 are Commands Bus in Laravel 5.0.

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

It is only a naming change because of the confusion between Console\Commands(commands run from the console) and The Command Bus(containing Commands) for the Application Tasks.

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

You should not confound :

你不应该混淆:

  • Command Bus: used for "encapsulating tasks your application" (from laravel 5.0 doc) which is now renamed a Jobs
  • Console\Commands: used for "Artisan [...] the command-line interface included with Laravel" (from laravel 5.1 docs) which is unchanged in Laravel since 4.x
  • Command Bus: 用于“封装你的应用程序的任务”(来自 laravel 5.0 文档),现在更名为 a Jobs
  • Console\Commands:用于“Artisan [...] Laravel 中包含的命令行界面”(来自 Laravel 5.1 文档),自 4.x 以来在 Laravel 中没有变化