Laravel 13 命令行进阶指南 Artisan 是 Laravel 的命令行接口,提供了丰富的命令来帮助开发。本文将深入探讨 Laravel 13 Artisan 命令行的高级用法。
创建命令 生成命令类 1 2 php artisan make:command SendEmails php artisan make:command ProcessOrders --command =orders:process
命令结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?php namespace App \Console \Commands ;use Illuminate \Console \Command ;use App \Services \OrderService ;class ProcessOrders extends Command { protected $signature = 'orders:process {--limit=100 : Maximum number of orders to process} {--force : Force processing without confirmation}' ; protected $description = 'Process pending orders' ; public function handle (OrderService $service ): int { $limit = $this ->option ('limit' ); $force = $this ->option ('force' ); if (! $force && ! $this ->confirm ('Do you want to process orders?' )) { $this ->info ('Operation cancelled.' ); return self ::SUCCESS ; } $processed = $service ->process ($limit ); $this ->info ("Processed {$processed} orders." ); return self ::SUCCESS ; } }
命令签名 参数 1 2 3 4 5 6 7 8 9 10 11 protected $signature = 'user:create {name}' ;protected $signature = 'user:create {name?}' ;protected $signature = 'user:create {name=Guest}' ;protected $signature = 'user:create {names*}' ;
选项 1 2 3 4 5 6 7 8 9 10 11 protected $signature = 'orders:process {--force}' ;protected $signature = 'orders:process {--limit=100}' ;protected $signature = 'orders:process {--L|limit=100}' ;protected $signature = 'orders:process {--id=*}' ;
完整签名示例 1 2 3 4 5 6 7 protected $signature = 'report:generate {type : Report type (daily|weekly|monthly)} {--date= : Specific date for the report} {--format=pdf : Output format (pdf|csv|excel)} {--email=* : Email addresses to send report} {--notify : Send notification when done} {--force : Overwrite existing report}' ;
获取输入 获取参数 1 2 $name = $this ->argument ('name' );$arguments = $this ->arguments ();
获取选项 1 2 $limit = $this ->option ('limit' );$options = $this ->options ();
输出 基本输出 1 2 3 4 $this ->info ('Operation completed successfully.' );$this ->error ('An error occurred.' );$this ->warning ('This action cannot be undone.' );$this ->line ('Plain text output' );
表格输出 1 2 3 4 $this ->table ( ['ID' , 'Name' , 'Email' ], User ::all (['id' , 'name' , 'email' ])->toArray () );
进度条 1 2 3 4 5 6 7 8 9 10 11 $users = User ::all ();$bar = $this ->output->createProgressBar (count ($users ));$bar ->start ();foreach ($users as $user ) { $user ->process (); $bar ->advance (); } $bar ->finish ();
列表输出 1 2 3 4 5 6 7 $this ->newLine ();$this ->line ('Users:' );$this ->newLine ();foreach ($users as $user ) { $this ->line (" - {$user->name} " ); }
交互 确认 1 2 3 4 5 if ($this ->confirm ('Do you want to continue?' )) {} if ($this ->confirm ('Do you want to continue?' , true )) {}
询问 1 2 3 $name = $this ->ask ('What is your name?' );$password = $this ->secret ('Enter your password' );$email = $this ->askForEmail ('What is your email?' );
选择 1 2 3 4 5 $role = $this ->choice ( 'Select user role' , ['admin' , 'editor' , 'user' ], 'user' );
预期输入 1 2 3 $this ->anticipate ('Search user' , function ($input ) { return User ::where ('name' , 'like' , "%{$input} %" )->pluck ('name' ); });
注册命令 自动发现 命令放在 app/Console/Commands 目录下会自动被发现。
手动注册 1 2 3 4 protected $commands = [ Commands\ProcessOrders ::class , ];
命令调度 定义调度 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 protected function schedule (Schedule $schedule ): void { $schedule ->command ('orders:process' ) ->daily () ->at ('02:00' ); $schedule ->command ('report:generate daily' ) ->daily () ->emailOutputTo ('admin@example.com' ); $schedule ->command ('cache:clear' ) ->hourly () ->withoutOverlapping (); $schedule ->command ('backup:run' ) ->daily () ->onSuccess (function () { Log ::info ('Backup completed' ); }) ->onFailure (function () { Log ::error ('Backup failed' ); }); }
调度频率 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $schedule ->command ('task' )->everyMinute ();$schedule ->command ('task' )->everyFiveMinutes ();$schedule ->command ('task' )->everyTenMinutes ();$schedule ->command ('task' )->everyFifteenMinutes ();$schedule ->command ('task' )->everyThirtyMinutes ();$schedule ->command ('task' )->hourly ();$schedule ->command ('task' )->hourlyAt (17 );$schedule ->command ('task' )->daily ();$schedule ->command ('task' )->dailyAt ('13:00' );$schedule ->command ('task' )->twiceDaily (1 , 13 );$schedule ->command ('task' )->weekly ();$schedule ->command ('task' )->weeklyOn (1 , '08:00' );$schedule ->command ('task' )->monthly ();$schedule ->command ('task' )->monthlyOn (4 , '15:00' );$schedule ->command ('task' )->quarterly ();$schedule ->command ('task' )->yearly ();$schedule ->command ('task' )->cron ('* * * * *' );
调度约束 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $schedule ->command ('task' ) ->weekdays () ->weekends () ->mondays () ->tuesdays () ->wednesdays () ->thursdays () ->fridays () ->saturdays () ->sundays () ->days ([1 , 15 ]) ->between ('08:00' , '17:00' ) ->unlessBetween ('12:00' , '13:00' ) ->when (function () { return date ('N' ) <= 5 ; }) ->skip (function () { return Holiday ::isToday (); });
调度选项 1 2 3 4 5 6 7 8 9 $schedule ->command ('task' ) ->withoutOverlapping (10 ) ->runInBackground () ->onOneServer () ->evenInMaintenanceMode () ->environments (['production' ]) ->when (function () { return true ; });
队列命令 队列工作进程 1 2 3 4 5 6 php artisan queue:work php artisan queue:work --queue=high,default php artisan queue:work --daemon php artisan queue:work --tries=3 php artisan queue:work --timeout =60 php artisan queue:work --memory=128
队列监听 1 2 php artisan queue:listen php artisan queue:listen --queue=high,default,low
队列重启 1 2 3 php artisan queue:restart php artisan queue:retry all php artisan queue:retry 5
内置命令 应用命令 1 2 3 4 5 6 7 php artisan down php artisan down --message="Upgrading database" php artisan down --retry=60 php artisan up php artisan serve php artisan serve --port=8080 php artisan serve --host=0.0.0.0
缓存命令 1 2 3 4 5 6 7 8 9 10 php artisan cache:clear php artisan cache:forget key php artisan config:cache php artisan config:clear php artisan route:cache php artisan route:clear php artisan view:cache php artisan view:clear php artisan event:cache php artisan event:clear
数据库命令 1 2 3 4 5 6 7 8 php artisan migrate php artisan migrate:rollback php artisan migrate:reset php artisan migrate:fresh php artisan migrate:refresh php artisan migrate:status php artisan db:seed php artisan db:wipe
生成命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 php artisan make:model User php artisan make:model User --migration php artisan make:controller UserController php artisan make:controller UserController --resource php artisan make:middleware CheckRole php artisan make:request StoreUserRequest php artisan make:resource UserResource php artisan make:factory UserFactory php artisan make:seeder UserSeeder php artisan make:policy UserPolicy php artisan make:rule ValidEmail php artisan make:job ProcessPodcast php artisan make:event OrderShipped php artisan make:listener SendNotification --event=OrderShipped php artisan make:mail WelcomeEmail php artisan make:notification InvoicePaid php artisan make:command ProcessOrders
自定义命令示例 数据导出命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 <?php namespace App \Console \Commands ;use Illuminate \Console \Command ;use App \Models \User ;use League \Csv \Writer ;class ExportUsers extends Command { protected $signature = 'users:export {--format=csv : Export format (csv|json)} {--output= : Output file path} {--active : Export only active users}' ; protected $description = 'Export users to file' ; public function handle ( ): int { $query = User ::query (); if ($this ->option ('active' )) { $query ->where ('active' , true ); } $users = $query ->get (); if ($users ->isEmpty ()) { $this ->warn ('No users found.' ); return self ::SUCCESS ; } $format = $this ->option ('format' ); $output = $this ->option ('output' ) ?: storage_path ("users-export.{$format} " ); $this ->info ("Exporting {$users->count()} users..." ); $bar = $this ->output->createProgressBar ($users ->count ()); $bar ->start (); match ($format ) { 'csv' => $this ->exportCsv ($users , $output , $bar ), 'json' => $this ->exportJson ($users , $output , $bar ), default => $this ->error ("Unsupported format: {$format} " ) }; $bar ->finish (); $this ->newLine (); $this ->info ("Export completed: {$output} " ); return self ::SUCCESS ; } private function exportCsv ($users , $output , $bar ): void { $csv = Writer ::createFromPath ($output , 'w+' ); $csv ->insertOne (['ID' , 'Name' , 'Email' , 'Created At' ]); foreach ($users as $user ) { $csv ->insertOne ([ $user ->id, $user ->name, $user ->email, $user ->created_at->toDateTimeString (), ]); $bar ->advance (); } } private function exportJson ($users , $output , $bar ): void { $data = []; foreach ($users as $user ) { $data [] = [ 'id' => $user ->id, 'name' => $user ->name, 'email' => $user ->email, 'created_at' => $user ->created_at->toDateTimeString (), ]; $bar ->advance (); } file_put_contents ($output , json_encode ($data , JSON_PRETTY_PRINT)); } }
最佳实践 1. 使用描述性签名 1 2 3 protected $signature = 'orders:process {--limit=100 : Maximum orders to process} {--force : Skip confirmation}' ;
2. 返回正确的退出码 1 2 3 4 5 6 7 8 public function handle ( ): int { if ($error ) { return self ::FAILURE ; } return self ::SUCCESS ; }
3. 使用进度条 1 2 3 4 5 6 7 8 9 $bar = $this ->output->createProgressBar (count ($items ));$bar ->start ();foreach ($items as $item ) { $this ->process ($item ); $bar ->advance (); } $bar ->finish ();
总结 Laravel 13 的 Artisan 命令行提供了强大的命令创建和管理能力。通过合理使用命令参数、选项、输出格式和交互功能,可以构建出功能丰富、用户友好的命令行工具。记住使用描述性的命令签名、返回正确的退出码、使用进度条提供反馈,并充分利用调度系统来自动化任务执行。Artisan 是 Laravel 开发的重要工具,掌握它对于构建高效的工作流程至关重要。