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:
Just an addition to the actual answers.
Jobs in Laravel >= 5.1 are Commands Bus in 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.
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.xI see those "objects" like so: (I added some code examples from one of my side projects)
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.
Example: A console command with fires a command to fetch images from Imgur. The Class FetchImages
contains the actual business logic of fetching images.
Class which contains the actual logic. You should also be able to call this command from your application with 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.
I made this app with Laravel 5.0 so jobs
weren'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 SelfHandling
and ShouldBeQueued
).
I see myself as an experienced Laravel Developer but those changes in Commands
and Jobs
are quite difficult to understand.
EDIT: From the Laravel Docs:
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.
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 5.0 introduced an implementation of the Command Bus
pattern - Command Bus Commands. (I believe these were renamed to Jobs because of the resulting confusion between them and CLI Commands).
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).
In laravel, you can declare a job to be self handling - that is, it has a handle method itself.
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.
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).
You can use the following to dispatch a command.
app('Illuminate\Bus\Dispatcher')->dispatch(new EmailPersonCommand('email@you.com', $otherdata));
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.
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 ShouldQueue
job to ->dispatch()
.
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
. You can call either of those methods directly instead of dispatch
with your command should you wish to override the default behaviour.
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.
- don't have it ShouldQueue
, and use dispatchToQueue
where you call it in your code.
From the sounds of it, i'd do the former.