Laravel Artisan Commands Reference
A reference for Laravel's Artisan command-line tool: built-in commands and writing your own.
Laravel Reference
Useful built-in commands
| Command | Does |
|---|---|
php artisan serve | Runs the built-in dev server. |
php artisan tinker | An interactive REPL with the app already booted — great for poking at models/queries. |
php artisan migrate | Runs pending migrations. Add --force to run without confirmation in production. |
php artisan migrate:rollback | Reverts the last migration batch. |
php artisan make:model Post -mfc | Generates a model plus, in one go, a migration (-m), factory (-f), and controller (-c). |
php artisan route:list | Lists every registered route. |
php artisan config:cache | Compiles all config files into one cached file for production performance. |
php artisan config:clear / cache:clear / route:clear / view:clear | Clear the respective cache — reach for these first when changes don't seem to take effect. |
php artisan queue:work | Processes queued jobs. |
php artisan schedule:work | Runs the task scheduler in the foreground, for local development. |
php artisan about | Prints a summary of the app's environment and configuration. |
Writing a custom command
php artisan make:command SendWeeklyDigest
class SendWeeklyDigest extends Command
{
protected $signature = 'digest:send {--dry-run}';
protected $description = 'Email the weekly digest to subscribed users';
public function handle(): int
{
$users = User::where('subscribed', true)->get();
$this->info("Sending to {$users->count()} users...");
if (! $this->option('dry-run')) {
$users->each(fn ($user) => Mail::to($user)->send(new WeeklyDigest($user)));
}
return self::SUCCESS;
}
}
php artisan digest:send
php artisan digest:send --dry-run
Signature syntax
| Syntax | Meaning |
|---|---|
{user} | Required argument. |
{user?} | Optional argument. |
{user=1} | Optional argument with a default. |
{--queue} | Boolean flag/option, e.g. --queue. |
{--queue=default} | Option that takes a value, with a default. |
User interaction and output
$this->info('All good.');
$this->warn('Careful.');
$this->error('Something failed.');
$name = $this->ask('What is your name?');
$confirmed = $this->confirm('Do you wish to continue?');
$choice = $this->choice('Pick an environment', ['local', 'staging', 'production']);
$this->table(['Name', 'Email'], $users->map->only(['name', 'email']));
$this->withProgressBar($users, function ($user) {
// ...
});
Running a command from code
use Illuminate\Support\Facades\Artisan;
Artisan::call('digest:send', ['--dry-run' => true]);
// Also how the scheduler runs commands
Schedule::command('digest:send')->weekly();
Artisan::call() runs the command synchronously in the current process and returns its exit code, which is handy for triggering one command from inside another. For anything that should run independently of the request lifecycle — a nightly digest, a report — scheduling it via Schedule::command() is almost always the better fit than calling it manually.
Tinker
php artisan tinker drops into a REPL with the full application already booted, so Eloquent models, facades, and helper functions are all available immediately — no bootstrapping required. It's the fastest way to check a query, inspect a model's relationships, or try out a snippet before committing it to a controller:
>>> User::where('subscribed', true)->count()
>>> $user = User::find(1);
>>> $user->posts()->latest()->first()
>>> event(new OrderShipped($order)); // fire an event manually
>>> Mail::to($user)->send(new WeeklyDigest($user));
Because Tinker holds the app in memory across calls, changes made to model files while a session is open aren't picked up until it's restarted — a common source of confusion when a fix "doesn't seem to work" in Tinker after an edit.
Command dependencies and testing
Like controllers, a command's handle() method supports method injection — Laravel resolves type-hinted arguments out of the container automatically, on top of whatever the signature captured:
public function handle(MailerService $mailer): int
{
$mailer->sendDigest();
return self::SUCCESS;
}
Commands are also straightforward to test without actually running them from the terminal, using the same testing helpers as HTTP tests:
$this->artisan('digest:send', ['--dry-run' => true])
->expectsOutput('Sending to 12 users...')
->assertExitCode(0);