Artisan Console Commands

Nearly every lesson so far has quietly relied on one tool without stopping to explain it properly: Artisan, Laravel's built-in command-line interface. Every Laravel project ships with an artisan file in its root directory, and every command runs through it as php artisan <command>. This lesson steps back to look at Artisan itself — the generators used throughout this track, useful maintenance commands, and how to build an entirely custom command of your own.

To see everything Artisan can do in a given project, list every registered command:

php artisan list

The make:* Generators Used Throughout This Track

Almost every file type covered in this tutorial — controllers, models, migrations, middleware, and more — is normally created with an Artisan generator rather than typed out from scratch, so that the boilerplate (namespace, base class, empty methods) is already correct from the first line:

CommandGenerates
make:controllerA controller class in app/Http/Controllers/
make:modelAn Eloquent model in app/Models/ (add -m to generate a migration alongside it)
make:migrationA migration class in database/migrations/
make:middlewareA middleware class in app/Http/Middleware/
make:requestA Form Request class in app/Http/Requests/
make:policyA policy class in app/Policies/
make:providerA service provider in app/Providers/
make:factoryA model factory in database/factories/
make:seederA database seeder in database/seeders/
Note: Every one of these has shown up earlier in this track under its own lesson — seeing them collected in one table is a good way to notice just how much of a typical Laravel feature (a model, its migration, its controller, its validation, its authorization) is scaffolded by Artisan before you write any actual business logic.

Everyday Maintenance Commands

Beyond generators, Artisan also handles the routine tasks of running and maintaining an application:

php artisan migrate        # run any pending migrations
php artisan db:seed         # run the database seeders
php artisan cache:clear     # flush the application cache
php artisan config:clear    # clear cached configuration
php artisan route:list      # list every registered route

route:list in particular is worth reaching for often — it's the fastest way to confirm a route actually exists, which HTTP verb it expects, and which controller method it points to, without hunting through routes/web.php by hand.

Creating a Fully Custom Command

Beyond the built-in commands, Artisan lets you register entirely new ones of your own — useful for any one-off or repeatable task better run from the terminal (or on a schedule) than through a web request. Generate the skeleton with its own generator:

php artisan make:command SendWeeklyDigest

This creates app/Console/Commands/SendWeeklyDigest.php with two key pieces already in place: a $signature property, and a handle() method.

<?php
// app/Console/Commands/SendWeeklyDigest.php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class SendWeeklyDigest extends Command
{
    protected $signature = 'send:weekly-digest';

    protected $description = 'Email a weekly activity digest to every user';

    public function handle(): int
    {
        // the actual logic that runs goes here
        return self::SUCCESS;
    }
}

$signature defines the command's name exactly as it will be typed on the command line — here, send:weekly-digest — and can also declare arguments and options the command accepts. handle() is where the real work happens, called automatically whenever the command runs.

Full Worked Example: Looping Over Users

Filling in handle() with real logic — iterating over every user and sending each one a digest email (using Laravel's Mail system, covered later in this track):

<?php
public function handle(): int
{
    User::query()->each(function (User $user) {
        Mail::to($user->email)->send(new WeeklyDigestMail($user));
    });

    $this->info('Weekly digest sent to all users.');

    return self::SUCCESS;
}

$this->info() is one of several helper methods available inside any command for writing colored, formatted output back to the terminal — useful for confirming progress when running a command manually. Once saved, the command is run exactly like any built-in Artisan command:

php artisan send:weekly-digest
Next up: Running this command by hand from the terminal works, but a "weekly" digest should really run itself — see Task Scheduling for how to have Laravel invoke a command like this one automatically, without any manual intervention. First, though, the next lesson covers a different way of decoupling logic: Events & Listeners.