简体   繁体   English

Laravel命令和工作

[英]Laravel commands and jobs

I was wondering what the difference is between the different command-like classes in Laravel 5.1. 我想知道Laravel 5.1中不同的类命令类之间有什么区别。 As far as I can tell Laravel 5.1 has the following available: 据我所知,Laravel 5.1提供以下服务:

  • Console commands ( artisan make:console ) 控制台命令( artisan make:console
  • Commands ( artisan make:command ) 命令( artisan make:command
    • Handlers ( artisan make::command --handler ) 处理程序( artisan make::command --handler
  • Jobs ( artisan make:job ) 工作( 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 ( just commands) 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. 我直接从4.2到5.1,所以我不知道在4.2和5.1之间发生了什么,但我被告知中间的( 只是命令)基本上不应该再被使用 - 它们来自当队列化的工作在5.0中成为“命令”时,Laravel自从决定反对这一点,并且他们只是为了兼容性。 However, I'm not 100% on this point, so clarification would be appreciated. 但是,我不是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. 起初这听起来像一个控制台命令 - 我希望能够从artisan那里开始运行它。 But I may also want it on a schedule (great, artisan schedule:run runs console commands). 但我可能也希望它按计划进行(很棒, artisan schedule:run运行控制台命令)。 But I may also want to execute it asynchronously from code. 但我可能也想从代码中异步执行它。 Console commands can be run synchronously with Artisan::call() , but for asynchronous, this is (I think) where queues come in, and it suddenly has to be a job. 控制台命令可以与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 DispatchesJobs trait (or the code therein) to it, and then dispatch the job? 我可以创建一个瘦控制台命令并在其中添加DispatchesJobs特征(或其中的代码),然后分派作业吗? 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? 作业是否总是必须排队,或者我们是否可以同步执行作业(理想情况下,输出到控制台命令的输出?)同样的问题是按计划运行它 - 我应该创建这个控制台命令并将其添加到调度程序,还是可以让调度程序直接运行该作业?

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. 正如我之前所说的那样,人们告诉我这些只是来自Laravel 5.0的代码更改(有点)还原。 But the artisan make command still exists for them, so they can't be that dead. 但是artisan make命令仍然存在,所以他们不能那么死。 Also, what's the deal with a self handling command (the default, comes with a handle method) and one that 'requires' a handler class (run artisan make:command --handler )? 此外,处理自我处理命令(默认情况下,带有handle方法)和“需要”处理程序类(运行artisan make:command --handler )的处理是什么? How do you actually make these execute? 你如何实际执行这些? Manually with (new App\\Command\\SomeCommand)->handle(); 手动用(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)? 或者(new App\\handlers\\SomeCommandHandler)->handle(new App\\Command\\SomeCommand) ,或者是否有一些我不知道的隐藏系统(也许它们可以使用作业/队列调度程序调度)? Also you can create 'queued' commands artisan make::command --queued , so how do these differ, too? 你也可以创建'排队'命令artisan make::command --queued ,那么它们也有什么不同呢?

I guess my question boils down to the following: 我想我的问题归结为以下几点:

  • What is the real (semantic and functional) 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命令和作业

Console Commands 控制台命令

Laravel has had console "commands" for some time. Laravel已经有一段时间的控制台“命令”了。 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... 它们与......无关

The Command Bus 命令总线

Laravel 5.0 introduced an implementation of the Command Bus pattern - Command Bus Commands. Laravel 5.0引入了Command Bus模式的实现 - 命令总线命令。 (I believe these were renamed to Jobs because of the resulting confusion between them and CLI Commands). (我相信这些被重命名为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中,您可以将作业声明为自我处理 - 也就是说,它本身具有句柄方法。

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. EmailCommand in the commands folder would have an EmailCommandHandler in the handlers folder). 在laravel 5.0的处理程序目录是隐式声明的关系(即一种方式EmailCommand中的命令文件夹将有一个EmailCommandHandler在处理程序文件夹)。

Dispatching a Command 调度命令

You can use the following to dispatch a command. 您可以使用以下命令来分派命令。

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

Queues 队列

Jobs, by default, will run as soon as they are called (or dispatched). 默认情况下,作业会在调用(或调度)后立即运行。 Setting them as ShouldQueue will 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. 如果您希望有时同步运行它们,而在其他时间异步运行它们,则可以在需要排队时调用$dispatcher->dispatchToQueue($job) This is all that happens internally when you pass a ShouldQueue job to ->dispatch() . 当您将ShouldQueue作业传递给->dispatch()时,这就是内部发生的一切。

edit: To Queuing (or not) 编辑:排队(或不排队)

I've just had a longer look at the dispatcher. 我刚看了一下调度员。 The dispatch method checks if the command is a ShouldQueue , and either forwards it to dispatchToQueue or dispatchNow . dispatch方法检查命令是否为ShouldQueue ,并将其转发到dispatchToQueuedispatchNow You can call either of those methods directly instead of dispatch with your command should you wish to override the default behaviour. 如果您希望覆盖默认行为,可以直接调用这些方法中的任何一种,而不是使用命令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 dispatchNow in the CLI Command. 因此,在您的情况下,取决于您的作业的“默认”行为(即,它通常会排队吗?): - 将它具有ShouldQueue ,并在CLI命令中使用dispatchNow - don't have it ShouldQueue , and use dispatchToQueue where you call it in your code. - 没有它的ShouldQueue ,并使用dispatchToQueue在你的代码中调用它。

From the sounds of it, i'd do the former. 从它的声音,我做前者。

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"). 我想从命令行执行的操作(正如您在“删除早于x的文件”中所提到的那样)。 But the thing is, you could extract the business logic of it to a command . 但问题是,您可以将其业务逻辑提取到命令中

Example : A console command with fires a command to fetch images from Imgur. 示例 :一个控制台命令,用于触发从Imgur获取图像的命令。 The Class FetchImages contains the actual business logic of fetching images. 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 jobs weren't a thing back then. 我用Laravel 5.0制作了这个应用程序,所以当时jobs不是一件事。 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 SelfHandling and ShouldBeQueued ). (正如您在这些示例中看到的那样,这些命令实现了您提到的Interfaces SelfHandlingShouldBeQueued )。


I see myself as an experienced Laravel Developer but those changes in Commands and Jobs are quite difficult to understand. 我认为自己是一位经验丰富的Laravel开发人员,但CommandsJobs中的这些变化很难理解。

EDIT: From the Laravel Docs: 编辑:来自Laravel文档:

The app/Commands directory has been renamed to app/Jobs. app / Commands目录已重命名为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. 但是,您不需要将所有命令移动到新位置,并且可以继续使用make:command和handler:命令Artisan命令来生成类。

Likewise, the app/Handlers directory has been renamed to app/Listeners and now only contains event listeners. 同样,app / Handlers目录已重命名为app / 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. 但是,您不需要移动或重命名现有的命令和事件处理程序,并且可以继续使用handler:event命令生成事件处理程序。

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

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\\Commands (从控制台运行的Command Bus )和Application Tasks(包含Commands )之间的混淆,它只是一个命名更改。

You should not confound : 你不应该混淆:

  • Command Bus : used for "encapsulating tasks your application" (from laravel 5.0 doc) which is now renamed a Jobs Command Bus :用于“封装您的应用程序的任务”(来自laravel 5.0 doc),现在已重命名为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 Console\\Commands :用于“Artraan [...] Laravel附带的命令行界面”(来自laravel 5.1 docs),自4.x以来在Laravel中保持不变

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM