Learn how to build custom Artisan commands to automate development tasks. Master CLI arguments, options, and console interaction to streamline your Laravel app.
Previously in this course, we explored Advanced Dependency Injection with Service Providers to manage complex object lifecycles. In this lesson, we shift our focus from the web request lifecycle to the CLI. By building custom commands, you'll turn the terminal into a powerful dashboard for managing your application's state.
As your application grows, you'll inevitably face repetitive tasks: clearing cache, generating dummy data for specific states, or triggering cleanup scripts. While you could write these in controllers, putting them in the CLI makes them accessible to CI/CD pipelines and local development workflows.
Artisan is built on the Symfony Console component. It provides a standardized way to define inputs (arguments and options) and output formatting, ensuring your custom tools feel like first-class citizens alongside core Laravel commands.
To create a new command, use the make:command Artisan generator. Let's build a tool for our project board that resets a specific project's task status to "pending" for debugging purposes.
Bashphp artisan make:command ResetProjectTasks
This creates a file in app/Console/Commands. Open it, and you'll see a $signature property. This string defines how the command is invoked and what inputs it accepts.
PHPprotected $signature = 'project:reset {projectId : The ID of the project} {--force : Force the reset even if project is locked}';
In the $signature above:
project:reset is the command name.{projectId} is a required argument.{--force} is an optional flag (boolean).Now, let's implement the handle() method. This is where your business logic lives. We'll inject our TaskService (which we built in our earlier lessons on Service-Oriented Task Management) to handle the actual data mutation.
PHPpublic function handle(TaskService $taskService): void { $projectId = $this->argument('projectId'); $force = $this->option('force'); if (!$force && $this->confirm("Are you sure you want to reset tasks for project {$projectId}?")) { return; } $taskService->resetTasksForProject($projectId); $this->info("Tasks for project {$projectId} have been reset successfully."); }
Key interaction methods:
$this->argument('name') / $this->option('name'): Retrieve input.$this->info('message'): Prints green text.$this->error('message'): Prints red text.$this->confirm('question'): Prompts the user for a yes/no response.$this->table(['Header'], $data): Renders a clean ASCII table.To advance our project board, your task is to create a command named project:stats {projectId}.
handle() method, fetch the project using your repository layer.$this->table() to display the count of "Open", "In Progress", and "Completed" tasks for that project.$this->error() to notify the user and exit.handle() method. Treat the command as a controller: it should only validate input, call a service or job, and format the output.handle() method just like you do in controllers. Don't resolve them manually via app() inside the method.try-catch blocks if the command interacts with external APIs or fragile data, and output the error using $this->error() so the user knows why the process stopped.Custom Artisan commands are the backbone of developer productivity in Laravel. By leveraging the $signature property, you can create expressive interfaces for your background tasks. Always keep your command logic thin by delegating to services, and use the built-in console helpers (info, error, table) to provide clear feedback to the user.
Up next: Scheduled Tasks and Cron Jobs. We'll look at how to automate these commands so they run without manual intervention.
Learn to master Laravel scheduling to automate recurring tasks like reporting and cleanup. Replace complex crontabs with clean, version-controlled PHP code.
Read moreMaster the Artisan CLI to automate repetitive tasks and debug your Laravel application. Learn how to list, create, and run custom commands today.
Command Line Tools with Artisan