Tools: Building CLI Commands in Laravel Artisan

Tools: Building CLI Commands in Laravel Artisan

Source: Dev.to

Key Takeaways: ## Table of Index ## 1. Introduction to Artisan CLI ## 2. Why Build Custom CLI Commands? ## 3. Generating an Artisan Command ## 4. Understanding Command Structure ## 5. Accepting Arguments and Options ## 6. Writing Interactive CLI Commands ## 7. Using Services, Models, and DB in CLI ## 8. Command Output Formatting ## 9. Registering Commands ## 10. Best Practices ## 11. FAQ ## 12. Interesting Facts & Insights: ## 13. Conclusion Don’t build features only for users - build commands for systems. That’s where real automation begins. – ‘Taylor Otwell’ Laravel Artisan is a powerful command-line interface (CLI) that comes built-in with the framework. It helps developers automate tasks, generate boilerplate code, schedule background jobs, interact with the application, and build custom CLI tools tailored to business needs. Creating your own Artisan command enables you to extend Laravel beyond HTTP and build highly efficient terminal utilities. Artisan is Laravel’s terminal assistant. Whether you're running migrations, clearing cache, managing queues, or scaffolding code, Artisan improves developer productivity. It also acts as a foundation for building custom automation scripts. Custom CLI commands are useful when: Laravel provides a simple command generator: This creates a new file under: If HTTP is Laravel’s voice, Artisan is its discipline - quiet, consistent, and unstoppable. – ‘Taylor Otwell’ A generated command contains key properties: And a handle() method where logic lives: You can prompt users inside the terminal: Laravel also supports choice inputs: Artisan is not just a CLI - it’s Laravel’s automation engine, transforming manual effort into repeatable terminal intelligence. You can access anything from your Laravel app: You can also dispatch jobs: Laravel provides rich CLI output helpers: Example table output: Laravel auto-loads commands placed in: But you can manually register in Kernel.php: Write commands that matter. Let Artisan execute them at scale. 1. What is Laravel Artisan? Ans:- Artisan is Laravel’s built-in CLI tool for running framework commands and custom terminal automation scripts. 2. Where are custom Artisan commands stored? Ans:- Inside: app/Console/Commands/ 3. How do I create a new Artisan command? Ans:- Run: php artisan make:command CommandName 4. What is the purpose of the signature property? Ans:- It defines how the command is called in the terminal, including arguments and options. 5. Can Artisan commands interact with the database? Ans:- Yes, you can use Eloquent models, Query Builder, or DB facade inside CLI commands. 6. What are command options in Artisan? Ans:- Flags that modify behavior, e.g., --force, --admin, defined in the command signature. 7. Does CLI support user input interaction? Ans:- Yes, using ask(), confirm(), choice(), secret() methods. Building CLI commands in Laravel Artisan unlocks a new layer of automation and control. It empowers developers to create reusable internal tools, execute background logic safely without HTTP exposure, and streamline workflows for both development and production environments. Laravel CLI commands are not just scripts — they are first-class citizens of your application, capable of interacting with your services, database, jobs, and business logic with the same power as controllers or API endpoints. About the Author: Abodh is a PHP and Laravel Developer at AddWeb Solution, skilled in MySQL, REST APIs, JavaScript, Git, and Docker for building robust web applications. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: php artisan make:command SendDailyReport Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: php artisan make:command SendDailyReport CODE_BLOCK: php artisan make:command SendDailyReport CODE_BLOCK: app/Console/Commands/SendDailyReport.php Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: app/Console/Commands/SendDailyReport.php CODE_BLOCK: app/Console/Commands/SendDailyReport.php CODE_BLOCK: protected $signature = 'report:daily'; protected $description = 'Send daily system report to admin'; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: protected $signature = 'report:daily'; protected $description = 'Send daily system report to admin'; CODE_BLOCK: protected $signature = 'report:daily'; protected $description = 'Send daily system report to admin'; CODE_BLOCK: public function handle() { $this->info("Daily report sent successfully!"); } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: public function handle() { $this->info("Daily report sent successfully!"); } CODE_BLOCK: public function handle() { $this->info("Daily report sent successfully!"); } CODE_BLOCK: protected $signature = 'user:create {name} {email}'; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: protected $signature = 'user:create {name} {email}'; CODE_BLOCK: protected $signature = 'user:create {name} {email}'; CODE_BLOCK: php artisan user:create "Alex" "[email protected]" Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: php artisan user:create "Alex" "[email protected]" CODE_BLOCK: php artisan user:create "Alex" "[email protected]" CODE_BLOCK: $name = $this->argument('name'); $email = $this->argument('email'); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: $name = $this->argument('name'); $email = $this->argument('email'); CODE_BLOCK: $name = $this->argument('name'); $email = $this->argument('email'); CODE_BLOCK: protected $signature = 'user:create {name} {email} {--admin}'; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: protected $signature = 'user:create {name} {email} {--admin}'; CODE_BLOCK: protected $signature = 'user:create {name} {email} {--admin}'; CODE_BLOCK: php artisan user:create "Alex" "[email protected]" --admin Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: php artisan user:create "Alex" "[email protected]" --admin CODE_BLOCK: php artisan user:create "Alex" "[email protected]" --admin CODE_BLOCK: if ($this->option('admin')) { $this->warn("Admin user will be created"); } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: if ($this->option('admin')) { $this->warn("Admin user will be created"); } CODE_BLOCK: if ($this->option('admin')) { $this->warn("Admin user will be created"); } CODE_BLOCK: $name = $this->ask("Enter user name"); $password = $this->secret("Enter password"); if ($this->confirm("Do you want to continue?")) { $this->info("User confirmed"); } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: $name = $this->ask("Enter user name"); $password = $this->secret("Enter password"); if ($this->confirm("Do you want to continue?")) { $this->info("User confirmed"); } CODE_BLOCK: $name = $this->ask("Enter user name"); $password = $this->secret("Enter password"); if ($this->confirm("Do you want to continue?")) { $this->info("User confirmed"); } CODE_BLOCK: $role = $this->choice("Select Role", ["User", "Manager", "Admin"], 0); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: $role = $this->choice("Select Role", ["User", "Manager", "Admin"], 0); CODE_BLOCK: $role = $this->choice("Select Role", ["User", "Manager", "Admin"], 0); CODE_BLOCK: use App\Models\User; use Illuminate\Support\Facades\DB; public function handle() { $users = User::count(); $logs = DB::table('activity_logs')->latest()->limit(5)->get(); $this->info("Total Users: " . $users); $this->table(["ID","Log"], $logs->map(fn($l)=>[$l->id,$l->log])); } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: use App\Models\User; use Illuminate\Support\Facades\DB; public function handle() { $users = User::count(); $logs = DB::table('activity_logs')->latest()->limit(5)->get(); $this->info("Total Users: " . $users); $this->table(["ID","Log"], $logs->map(fn($l)=>[$l->id,$l->log])); } CODE_BLOCK: use App\Models\User; use Illuminate\Support\Facades\DB; public function handle() { $users = User::count(); $logs = DB::table('activity_logs')->latest()->limit(5)->get(); $this->info("Total Users: " . $users); $this->table(["ID","Log"], $logs->map(fn($l)=>[$l->id,$l->log])); } CODE_BLOCK: SendDailyReportJob::dispatch(); $this->info("Job dispatched!"); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: SendDailyReportJob::dispatch(); $this->info("Job dispatched!"); CODE_BLOCK: SendDailyReportJob::dispatch(); $this->info("Job dispatched!"); CODE_BLOCK: $this->table( ["Name", "Email"], [["Abodh", "[email protected]"], ["Kumar", "[email protected]"]] ); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: $this->table( ["Name", "Email"], [["Abodh", "[email protected]"], ["Kumar", "[email protected]"]] ); CODE_BLOCK: $this->table( ["Name", "Email"], [["Abodh", "[email protected]"], ["Kumar", "[email protected]"]] ); CODE_BLOCK: app/Console/Commands Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: app/Console/Commands CODE_BLOCK: app/Console/Commands CODE_BLOCK: protected $commands = [ Commands\SendDailyReport::class, ]; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: protected $commands = [ Commands\SendDailyReport::class, ]; CODE_BLOCK: protected $commands = [ Commands\SendDailyReport::class, ]; - Laravel Artisan CLI automates business and DevOps tasks. - Supports flexible arguments and options for configurable commands. - Enables interactive terminal UX with prompts and choices. - Provides full access to models and database inside CLI. - Allows async execution by dispatching background jobs. - Runs recurring tasks reliably using Laravel Scheduler. - Introduction to Artisan CLI - Why Build Custom CLI Commands? - Generating an Artisan Command - Understanding Command Structure - Accepting Arguments and Options - Writing Interactive CLI Commands - Using Services, Models, and DB in CLI - Command Output Formatting - Registering Commands - Best Practices - Interesting Facts - You want to automate repetitive tasks (e.g., data imports, cleanup, reports) - You need to trigger jobs or services manually - You want to build internal tools for DevOps, monitoring, or administration - You want terminal-based workflows without exposing HTTP endpoints - You need scheduled background processes via CLI - Keep commands single-purpose - Use service classes instead of heavy logic inside handle() - Add meaningful signature namespaces (module:task) - Log command activities for debugging - Make commands interactive when needed - Use scheduling instead of manual cron jobs - Artisan is more than a CLI – it’s Laravel’s automation engine that transforms manual tasks into repeatable workflows. https://laravel.com/docs/12.x/artisan? - Developers can create custom commands using php artisan make:command CommandName, giving full access to models, https://laravel.com/docs/12.x/artisan? - Commands can accept arguments and options, making them flexible and configurable for different scenarios. https://laravel.com/docs/12.x/artisan?utm_source - Interactive CLI features like ask(), secret(), confirm(), and choice() allow dynamic user input directly in the terminal. https://laravel.com/docs/12.x/artisan?utm_source - Artisan supports rich output formatting: info(), warn(), error(), and table() make messages clear and professional. https://laravel.com/docs/12.x/artisan?utm_source - Background jobs can be dispatched asynchronously from commands using Job::dispatch(). https://laravel.com/docs/12.x/queues?utm_source - Laravel Scheduler allows recurring CLI tasks to run reliably without manual cron jobs. - Best practices include keeping commands single-purpose, using service classes, meaningful signature namespaces, and logging activities. https://laravel-doc.readthedocs.io/en/latest/artisan/?utm_source - The philosophy behind Artisan emphasizes strategic automation: “Write commands that matter. Let Artisan execute them at scale.” https://laravel.com/docs/12.x/artisan?