我想知道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中成为'commands'时,但Laravel自此决定反对这一点,并且他们在这一点上并非100%,所以澄清将是值得赞赏的 .
我的具体用例是我想要一个地方放置一个独立的“可运行”任务 . 例如,某些东西将从给定目录中删除超过5天的文件(但它可以执行任何操作) .
起初这听起来像一个控制台命令 - 我希望能够从 artisan
开始运行它 . 但我可能也希望它按计划进行(很棒, artisan schedule:run
运行控制台命令) . 但我可能也想从代码中异步执行它 . 控制台命令可以与 Artisan::call()
同步运行,但对于异步,这是(我认为)队列进入的地方,它突然变成了一个工作 .
好的,我们有一份工作 . 我们现在可以从代码中将它添加到队列中,但是我们如何将它作为工匠命令(同步)执行?我可以创建一个瘦控制台命令并在其中添加 DispatchesJobs
特征(或其中的代码),然后分派作业吗?作业总是必须排队,还是我们可以同步执行作业(理想情况下,输出到控制台命令的输出?)同样的问题是按计划运行它 - 我应该创建这个控制台命令并将其添加到调度程序,还是可以让调度程序直接运行作业?
最后,我们有'commands'不是控制台命令,也不是工作 . 正如我之前所说的那样,人们告诉我这些只是来自Laravel 5.0代码更改(有点)还原 . 但是 artisan make
命令对他们来说仍然存在,所以他们不能那么死 . 另外,处理自我处理命令(默认情况下, handle
方法)和'requires'处理程序类(运行 artisan make:command --handler
)的处理是什么?你如何实际执行这些?手动使用 (new App\Command\SomeCommand)->handle();
或 (new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand)
,或者是否有一些隐藏的系统我没有't know about (maybe they can be dispatched using the job/queue dispatcher)? Also you can create '排队'命令 artisan make::command --queued
,那么它们有何不同呢?
我想我的问题归结为以下几点:
-
它们之间真正的(语义 and 功能)区别是什么?
-
'run'的正确方法是什么?
-
哪种方式最适合我需要运行的通常独立的代码,以我认为合适的方式?
我在文档中找到了有关如何使用队列和创建控制台命令的信息,但没有关于何时使用它们或在命令类和处理程序上的任何内容的确切信息 .
相关但不完全相同(也是,没有答案):Laravel 5.1 commands and jobs
3 回答
控制台命令
Laravel已经有了一段时间的控制台“命令” . 它们基本上没有变化,并且像往常一样工作 . 简单来说,它们相当于命令行的路径 - 应用程序的入口点 . 它们与...没有任何关系
命令总线
Laravel 5.0引入了
Command Bus
模式的实现 - 命令总线命令 . (我相信这些被重命名为Jobs,因为它们与CLI命令之间产生了混淆) .命令总线作为两个部分 - 表示要执行的命令的对象,具有所需的任何和所有数据(作业),以及执行命令的类(处理程序) .
处理程序
在laravel中,您可以将作业声明为自我处理 - 也就是说,它本身具有句柄方法 .
如果要注册命令处理程序,可以在服务提供者中调用以下内容:
其中Job是作业的类名,Handler是处理程序的类名 .
laravel 5.0中的处理程序目录是一种隐式声明这些关系的方式(即命令文件夹中的
EmailCommand
在处理程序文件夹中会有EmailCommandHandler
) .调度命令
您可以使用以下命令来分派命令 .
队列
默认情况下,作业会在调用(或调度)后立即运行 . 将它们设置为
ShouldQueue
将始终在分派时将它们传递给队列 .如果您希望有时同步运行它们,而在其他时间异步运行它们,则可以在希望它们排队时调用
$dispatcher->dispatchToQueue($job)
. 当您将ShouldQueue
作业传递给->dispatch()
时,这就是内部发生的一切 .编辑:排队(或不排队)
我刚看了一下调度员 .
dispatch
方法检查命令是否为ShouldQueue
,并将其转发到dispatchToQueue
或dispatchNow
. 您可以直接调用这些方法中的任何一种如果您希望覆盖默认行为,请使用您的命令代替dispatch
.那么在你的情况下,取决于你的工作的"default"行为是什么(即它通常会排队吗?): - 让它
ShouldQueue
,并在CLI命令中使用dispatchNow
. - 没有它ShouldQueue
,并使用dispatchToQueue
在您的代码中调用它 .从它的声音,我做前者 .
只是对实际答案的补充 .
Jobs in Laravel >= 5.1 are Commands Bus in Laravel 5.0 .
由于
Console\Commands
(从控制台运行的命令)与应用程序任务的Command Bus
(包含Commands
)之间的混淆,它只是一个命名更改 .你不应该混淆:
Command Bus
:用于"encapsulating tasks your application"(来自laravel 5.0 doc),现在重命名为Jobs
Console\Commands
:用于"Artisan [...] the command-line interface included with Laravel"(来自laravel 5.1 docs),自4.x以来在Laravel中保持不变我看到那些“对象”是这样的:(我在我的一个项目中添加了一些代码示例)
控制台
我想从命令行执行的操作(正如您在"Delete Files older than x"的示例中提到的那样) . 但事实是,你可以将它的业务逻辑提取到 command .
Example:一个控制台命令,用于触发从Imgur获取图像的命令 . 类
FetchImages
包含获取图像的实际业务逻辑 .命令
包含实际逻辑的类 . 您还应该能够使用
app()->make(Command::class)->handle()
从应用程序中调用此命令 .Example:示例1中提到的命令 . 包含对Imgur执行实际API调用并处理返回数据的逻辑 .
乔布斯
我用Laravel 5.0制作了这个应用程序,所以
jobs
当时不是一件事 . 但正如我所看到的,乔布斯就像命令,但它们排队等待,可以派遣 . (正如您在这些示例中看到的那样,这些命令实现了您提到的接口SelfHandling
和ShouldBeQueued
) .我认为自己是一位经验丰富的Laravel开发者,但是
Commands
和Jobs
中的那些变化很难理解 .编辑:来自Laravel文档: