Laravel命令未显示在php artisan list中需检查自动发现条件:命名空间为App\Console\Commands、类名以Command结尾、文件位于app/Console/Commands/目录;缺一不可,且修改后须执行php artisan config:clear刷新缓存。

命令没出现在 php artisan list 里?先检查自动发现是否生效
Laravel 8+ 默认启用命令自动发现,但前提是类必须满足三个硬性条件:命名空间为 App\Console\Commands、类名以 Command 结尾、文件放在 app/Console/Commands/ 目录下。只要缺一个,php artisan list 就不会显示它。
常见掉坑点:
- 手动新建文件但忘了加
Command后缀(比如叫SendReport.php而非SendReportCommand.php) - 改过类名或命名空间后没清缓存:
php artisan config:clear必须执行,否则自动发现机制读的是旧缓存 - 用了自定义命名空间(如
App\Commands),那就得退回到老方式:手动在app/Console/Kernel.php的$commands数组里注册
$signature 怎么写才支持参数和选项
$signature 不是随便写的字符串,它是 Artisan 解析输入的 DSL。写错会导致 $this->argument() 或 $this->option() 拿不到值,甚至命令直接报错退出。
关键规则:
- 必填参数用
{name},例如send:report {user_id}→$this->argument('user_id')返回字符串 - 可选参数加问号:
{user_id?},带默认值写成{user_id?=1} - 选项必须带
--前缀,要传值就加=:{--force}(布尔开关)、{--path=}(接收值)、{--path=default.txt}(带默认值) - 缩写用
|连接:{--env=|e=production},这样既支持--env=local也支持-e local - 数组参数/选项末尾加
*,且必须是最后一个,例如{ids*}→ 输入php artisan cmd 1 2 3会得到[1,2,3]
交互和输出别用 echo 或 var_dump
Artisan 命令运行在 CLI 环境,echo 和 print_r 会绕过 Laravel 的输出美化与颜色控制,还可能破坏进度条、确认提示等交互逻辑。
正确做法:
- 用户提问用
$this->ask('请输入邮箱')、$this->confirm('确定删除?')、$this->choice('选哪个', ['A','B'], 0) - 输出信息用
$this->info('✅ 成功')、$this->warn('⚠️ 注意')、$this->error('❌ 失败'),它们自动加换行和颜色 - 输出表格或进度条用
$table = $this->table(...)或$bar = $this->output->createProgressBar(...),别自己拼字符串 - 调试时想看变量内容,用
$this->line(var_export($data, true)),而不是dd()—— 后者会中断命令流程
耗时操作不处理信号,命令就无法被 Ctrl+C 中断
如果命令里有循环、队列监听或长 HTTP 请求,直接运行会卡死终端。用户按 Ctrl+C 时,PHP 默认忽略 SIGINT 信号,进程继续跑。
必须手动注册信号处理器:
- 在
handle()开头加pcntl_async_signals(true);(PHP 7.1+) - 然后用
pcntl_signal(SIGINT, function () { exit(130); });捕获中断 - 如果用了
sleep()或usleep(),记得每轮循环后调用pcntl_signal_dispatch(),否则信号不会被及时响应 - 注意:Windows 不支持
pcntl_*函数,这类命令在 Windows 下天然不可中断,得提前文档注明
最常被忽略的是信号处理和配置缓存刷新——这两处出问题,命令要么“看不见”,要么“关不掉”,排查起来特别花时间。











