Laravel Artisan 命令手册(中文整理版)

本文档基于 Laravel Artisan 命令行工具生成,包含所有内置命令及说明。最后更新:2026年03月09日

🧰 全局选项 (Global Options)

选项说明
-h, --help显示指定命令的帮助信息。未指定命令时显示 list 命令帮助
--silent不输出任何消息
-q, --quiet仅显示错误信息,抑制其他所有输出
-V, --version显示当前应用版本
--ansi/--no-ansi强制启用/禁用 ANSI 输出
-n, --no-interaction禁用任何交互式提问
--env[=ENV]指定命令运行的环境
-v|vv|vvv, --verbose增加消息详细程度:-v = 正常输出-vv = 更详细输出-vvv = 调试级别输出

🚀 核心命令 (Available Commands)

命令说明
about显示应用基本信息
clear-compiled移除编译后的类文件
completion生成 shell 自动补全脚本
db启动新的数据库 CLI 会话
docs访问 Laravel 官方文档
down将应用置于维护/演示模式
env显示当前框架环境
help显示命令帮助信息
inspire显示一句激励名言
list列出所有可用命令
migrate执行数据库迁移
optimize缓存框架启动、配置和元数据以提升性能
pail实时追踪应用日志
reload重载运行中的服务
serve通过 PHP 开发服务器提供应用服务
test运行应用测试
tinker与应用进行交互式调试
up将应用从维护模式恢复

🔐 认证 (auth)

命令说明
auth:clear-resets清除过期的密码重置令牌

⚡ 缓存 (cache)

命令说明
cache:clear清除应用缓存
cache:forget从缓存中移除指定项
cache:prune-stale-tags清理缓存中过期的标签(仅限 Redis)

📡 广播频道 (channel)

命令说明
channel:list列出所有已注册的私有广播频道

⚙️ 配置 (config)

命令说明
config:cache创建配置缓存文件以加速加载
config:clear移除配置缓存文件
config:publish将配置文件发布到应用中
config:show显示指定配置文件或键的所有值

💾 数据库 (db)

命令说明
db:monitor监控指定数据库的连接数量
db:seed用记录填充数据库
db:show显示指定数据库的信息
db:table显示指定数据表的信息
db:wipe删除所有表、视图和类型

🌍 环境 (env)

命令说明
env:decrypt解密环境文件
env:encrypt加密环境文件

🔔 事件 (event)

命令说明
event:cache发现并缓存应用的事件和监听器
event:clear清除所有缓存的事件和监听器
event:list列出应用的所有事件和监听器

📦 安装 (install)

命令说明
install:api创建 API 路由文件并安装 Laravel Sanctum 或 Passport
install:broadcasting创建广播频道路由文件

🔑 密钥 (key)

命令说明
key:generate设置应用密钥

🌐 语言 (lang)

命令说明
lang:publish发布所有可自定义的语言文件

🛠️ 生成器 (make)

命令说明
make:cache-table [cache:table]为缓存数据库表创建迁移文件
make:cast创建新的自定义 Eloquent 类型转换类
make:channel创建新的频道类
make:class创建新类
make:command创建新的 Artisan 命令
make:component创建新的视图组件类
make:config [config:make]创建新的配置文件
make:controller创建新的控制器类
make:enum创建新的枚举类
make:event创建新的事件类
make:exception创建新的自定义异常类
make:factory创建新的模型工厂
make:interface创建新接口
make:job创建新的任务类
make:job-middleware创建新的任务中间件类
make:listener创建新的事件监听器类
make:mail创建新的邮件类
make:middleware创建新的 HTTP 中间件类
make:migration创建新的迁移文件
make:model创建新的 Eloquent 模型类
make:notification创建新的通知类
make:notifications-table [notifications:table]为通知表创建迁移文件
make:observer创建新的观察者类
make:policy创建新的策略类
make:provider创建新的服务提供者类
make:queue-batches-table [queue:batches-table]为批次数据库表创建迁移文件
make:queue-failed-table [queue:failed-table]为失败队列任务数据库表创建迁移文件
make:queue-table [queue:table]为队列任务数据库表创建迁移文件
make:request创建新的表单请求类
make:resource创建新的 API 资源类
make:rule创建新的验证规则
make:scope创建新的作用域类
make:seeder创建新的填充器类
make:session-table [session:table]为会话数据库表创建迁移文件
make:test创建新的测试类
make:trait创建新的 Trait
make:view创建新视图

🔄 迁移 (migrate)

命令说明
migrate:fresh删除所有表并重新运行所有迁移
migrate:install创建迁移仓库
migrate:refresh重置并重新运行所有迁移
migrate:reset回滚所有数据库迁移
migrate:rollback回滚最后一次数据库迁移
migrate:status显示每个迁移的状态

🧑‍💻 模型 (model)

命令说明
model:prune清理不再需要的模型
model:show显示 Eloquent 模型信息

⚡ 优化 (optimize)

命令说明
optimize:clear移除缓存的引导文件

📦 包管理 (package)

命令说明
package:discover重建缓存的包清单

🐞 Pest 测试 (pest)

命令说明
pest:dataset创建新的数据集文件
pest:test创建新的测试文件

📮 队列 (queue)

命令说明
queue:clear删除指定队列中的所有任务
queue:failed列出所有失败的队列任务
queue:flush清空所有失败的队列任务
queue:forget删除失败的队列任务
queue:listen监听指定队列
queue:monitor监控指定队列的大小
queue:pause暂停特定队列的任务处理
queue:prune-batches清理批次数据库中的过期条目
queue:prune-failed清理失败任务表中的过期条目
queue:restart在当前任务完成后重启队列工作进程
queue:resume [queue:continue]恢复已暂停队列的任务处理
queue:retry重试失败的队列任务
queue:retry-batch重试批次中失败的任务
queue:work作为守护进程开始处理队列任务

🛣️ 路由 (route)

命令说明
route:cache为更快的路由注册创建缓存文件
route:clear移除路由缓存文件
route:list列出所有已注册路由

⛵ Sail (sail)

命令说明
sail:add向现有 Sail 安装添加服务
sail:install安装 Laravel Sail 默认的 Docker Compose 文件
sail:publish发布 Laravel Sail Docker 文件

⏱️ 任务调度 (schedule)

命令说明
schedule:clear-cache删除调度器创建的缓存互斥文件
schedule:interrupt中断当前正在运行的调度任务
schedule:list列出所有计划任务
schedule:run运行计划命令
schedule:test运行计划命令(测试用)
schedule:work启动调度工作进程

📐 数据库模式 (schema)

命令说明
schema:dump导出指定数据库的模式

💾 存储 (storage)

命令说明
storage:link创建配置的符号链接
storage:unlink删除配置的符号链接

🖋️ 存根 (stub)

命令说明
stub:publish发布所有可自定义的存根文件

📦 供应商 (vendor)

命令说明
vendor:publish从供应商包发布可发布资源

👁️ 视图 (view)

命令说明
view:cache编译所有 Blade 模板
view:clear清除所有编译后的视图文件

一人公司的效率核心:搭建可复用工具库

作为一人公司,核心挑战之一在于无法精准预判哪款产品能实现盈利。因此,通过规模化开发产品、以数量试错寻找成功机会,成为最现实的策略。但在这一过程中,重复开发同类功能模块会严重消耗时间与精力 —— 从用户登录、数据统计到支付接口,诸多功能在不同产品中都存在复用需求。

此时,搭建专属 “工具库” 就显得至关重要:对于高频复用的功能,不仅无需重复开发,更要实现 “几行代码即可调用” 的极致效率,如同主板上的标准化接口与插头,即插即用、无需额外调试。

典型场景:支付模块的复用价值

以支付功能为例:若你计划开发 20 款产品,其中 10 款需要集成支付能力,传统模式下的重复开发会造成双重浪费:

  1. 首次开发需投入大量时间对接支付渠道、调试流程、处理异常场景;
  2. 后续每款产品集成时,仍需重复适配、测试,且容易出现兼容性问题。

更优的解决方案是将支付功能封装为独立的内部产品:

  • 完整实现支付流程、回调处理、订单管理等核心能力;
  • 编写详细的注释文档与调用指南,明确输入参数、输出结果及异常处理方式;
  • 预留灵活的配置接口,适配不同产品的定价规则、支付渠道需求。

这样一来,后续任何产品需要集成支付功能时,只需调用工具库中的接口,几行代码就能完成部署,甚至可直接交给 AI 根据文档自动生成调用代码,彻底解放重复劳动。

工具库的持续迭代:边开发边沉淀

支付模块只是众多可复用功能的一个缩影。在实际开发中,还有大量场景值得纳入工具库:

  • 通用功能:用户注册登录、短信 / 邮件通知、数据备份与恢复;
  • 业务模块:表单提交验证、文件上传下载、第三方接口对接(地图、短信等);
  • 基础组件:日志记录、错误监控、权限控制。

一人公司的工具库建设,核心逻辑是 “开发即沉淀”:在每完成一款新产品的开发后,及时梳理其中可复用的功能模块,按 “标准化、文档化、低耦合” 的原则进行封装,逐步丰富工具库的内容。

随着工具库的完善,后续开发新产品的效率会呈指数级提升 —— 大部分基础功能无需从零开始,只需聚焦产品的核心差异化亮点,将精力集中在创意实现与用户体验优化上,真正实现 “用工具库支撑数量,用差异化赢取质量”。

工具库不仅是一人公司的效率利器,更是对抗资源有限性的核心竞争力:它让你无需在重复劳动中内耗,能以更少的时间开发更多产品,在数量试错的道路上跑得更快、更稳。

Android 打包(构建)api不显示备案所需的MD5如何处理?

大部分的时候开发app都是给自己用,在手机上安装就可以了。

但是如果你想把你的apk上传到各大市场去,给别人使用,那么在中国大陆你的app就一定要备案。

在备案的过程中有一项就是填写你的MD5指纹,具体是什么,大家可以去搜索下,这里不过多的阐述了。

如果Android Studio是老版本的话,在构建apk的时候会让你选择是否使用版本1和版本2进行签名,如下:

但是如果是比较新的版本Android Studio是没有选择的,如下图所示:

而且我们通过新版本的Android Studio创建的密钥也没有MD5,

原因是Google公司觉得MD5不安全,所以隐藏了,所以一般你去看指纹的话只有SHA1和SHA256的信息。

但是备案需要,我们可以通过其他方式可以获取。

  • 第一步:手动或者自动获取Key文件
keytool -genkeypair -v -keystore my-app-release.jks -keyalg RSA -keysize 2048 -validity 36500 -alias app-release-key

my-app-release.jks:名称,app-release-key:别名,自己自定义就可以了。

  • 生成文件证书(为了获取md5)
keytool -exportcert -keystore my-app-release.jks -alias app-release-key -file cert.cer
  • 显示(备案)md5
certutil -hashfile cert.cer MD5
  • 生成(备案)公钥
certutil -encode cert.cer cert_base64.txt

这样基本上能解决新版本Android Studio不显示md5的情况了。

JavaScript 中 箭头函数(Arrow Function)的语法差异.

bug重现

在项目调试的时候,发现javascript在过滤数组的时候,发现竟然为空数组。

var ages = [32, 33, 16, 40]; //想要获取除了第二个元素外的所有元素
//第一种写法:
var a = ages.filter((_, index) => index !== 1);

//第二种写法:
var a = ages.filter((_, index) => { index !== 1 });

这两种写法,就因为有一个{}导致结果完全不一样,第一种写法能够返回预想中的效果。

第二种写法就会返回一个空的数组。

原因

  • 第一种写法,没有{},那么他就不是一个代码块,等于直接返回 index !== 1 的元素。
  • 第二种写法,因为有{},那么就是一个代码块,而我们没有给return,那么就返回一个undefined。

修改:

如果我们硬性要求添加{},那么我们就应该添加一个return

var a = ages.filter((_, index) => { return index !== 1 });

写个简单的加密解密的传输数据

在Android开发或者其他需要通讯的过程中我们都喜欢把参数进行加密来保证数据在传输过程中的安全。

这里我们用java写个简单的对称加密解密算法。

package xxx.xxx

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.security.SecureRandom;
import java.util.Base64;


public class CryptionUtil {

    /**
     * 内容加密
     * @param content 需要加密的内容
     * @param secretKey 密钥
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String secretKey) throws Exception {
        byte[] key = Base64.getDecoder().decode(secretKey);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        byte[] cipherText = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        String res = Base64.getEncoder().encodeToString(cipherText);
        return String.join("~split~", Base64.getEncoder().encodeToString(iv), res);
    }

    /**
     * 内容解密
     * @param cipherText 需要解密的内容
     * @param secretKey 解密密钥
     * @return
     * @throws Exception
     */
    public static String decrypt(String cipherText, String secretKey) throws Exception {
        byte[] key = Base64.getDecoder().decode(secretKey);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

        String[] arr = cipherText.split("~split~");
        if (arr == null || arr.length != 2) {
            throw new InvalidParameterException();
        }
        byte[] iv = Base64.getDecoder().decode(arr[0]);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

        byte[] decryptedText = cipher.doFinal(Base64.getDecoder().decode(arr[1]));
        return new String(decryptedText, StandardCharsets.UTF_8);
    }


}

现在我们简单的测试下:

加密

      

        HashMap<String,Object> params = new HashMap<>();
        params.put("id","66937s9nnah2779293223hhad");
        params.put("content_type","userinfo");
        params.put("title","这是标题");
        params.put("name","这是姓名");
        params.put("image","https://blog.jishuge.cn/avtar.jpg");


        try {
            String key = "ABCDT5F8Dgn12345";  //这里是密钥,加密和解密都用到它,不传输
            String seceretKey = Base64.getEncoder().encodeToString(key.getBytes());
            String encrypt = CryptionUtil.encrypt(JSONObject.toJSONString(params),seceretKey);
            System.out.println(encrypt);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

解密

        //被加密之后的密文
        String message = "sGSCA05A9aBY0rIKwgWkEQ==~split~cRFS++NpEZGHZXW06k0p/0l3o4Et2+PrZpr1GYx3TkO8Zj9T725bhB5OzEubwhfxEMOf67qG4U/xXGLgXBdMGhupVpOFaLCOzHJUCuoYWbo=";
        String key = "ABCDT5F8Dgn12345";
        String seceretKey = Base64.getEncoder().encodeToString(key.getBytes());
        try {
            String decrypt = CryptionUtil.decrypt(message,seceretKey);
             System.out.println(decrypt);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

我们这个算法设置的密钥必须是16位,自己可以根据自己的需求来修改密钥长度。

SpringBoot 3.4.0置顶Redis数据库Unable to connect to Redis 错误

正常配置

spring:
  data:
    redis:
      host: 127.0.0.1
      port: 6379
      password: 123456
      database: 6

如果以上配置在3.4.0中使用,那么系统提示:Unable to connect to Redis,连接上不上redis服务器。

在3.4.0之前的版本是可以执行的。3.4.0的版本去掉database指定数据库

spring:
  data:
    redis:
      host: 127.0.0.1
      port: 6379
      password: 123456

这样就正常了。

解决electron安装慢的问题。

如果是在国内安装electron项目,我们发现安装很慢,甚至失败。

我们即使更换了npm的源,也是安装失败或者缓慢,

根本的原因是electron的包是直接从github上面下载的,而且大约90M的体积。

那么下载速度就几十KB的速度,非常慢,甚至中断。

那么我们可以手动的设置electron的镜像源,这样就不用直接去github下载了。

操作如下

首先通过设置环境变量当独设置electron的镜像源。

$env:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"

然后执行下载代码

npm install --save-dev electron

Android Gradle 国内配置

1、分发配置

  • 位置:项目根目录/gradle/wrapper/gradle-wrapper.properties
修改成腾讯云的源地址x.x是你的版本,这个不用替换,只要替换域名和后面的路径。
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-x.x-bin.zip

2、增加包的下载源

  • 位置:项目的根目录/settings.gradle

Google的注释之后会有问题。但是也可以先尝试用aliyun下载大部分包,如果不行,再还原回来,剩下的用google源下载。

然后同步更新就可以了,如果旧的配置已经在更新中了,可以直接关闭Android Studio IDEA然后再打开。

全局变量带来的bug。

在类中定义了一个全局变量List<String> list存储用请求得到的结果,但是每次使用之前没有忘记清空,导致数据就会叠加在里面,结果就是后面使用的用户,能看到前面那位用户请求的结果。

幸好项目的数据不是非常敏感,如果是非常重要的信息,那么这将会是史诗级的程序灾难。

这让我想起了上次阿里云盘导致的权限问题,也是用户能看到其他用户的信息,而阿里的主要技术编程是java,那么真正引起的问题是不是某个程序定义了一个全局变量,而这个全局变量又没有进行及时的清空导致的呢?

VUE3中使用动态组件

有时候一个页面中我们需要加载很多个组件,而且这些组件需要根据服务器请求的数据来判断该用哪个组件。

举个使用场景:我们在做IM或者客服软件,在加载聊天记录的时候,就要根据服务器给出不同类型的消息加载不同的消息组件,有文本,图片,视频,音频,表情,附件等等。

如果我们用v-if也是可以做的,在组件多的情况下代码看起来就特别的臃肿,那么我们这个时候就可以用动态组件来做这个事情。

我们使用vue框架提供的动态组件component来做。

<component :is="item.component" v-for="(item,index) in messageList":key="index" :message="item"></component>

如果此代码放在vue2中是完全没有问题的,因为item.component是动态的组件名称。如果在vue3中就无效了。

原因是vue3使用的是组件实例,不再是组件名称。

那么我们需要添加一些东西

<script setup>
import ComA "./ComponentA";
import ComB "./ComponentB";

defineOptions({
  components: {
    ComA , ComB 
  }
})

</script>

我看网络上有写说用resolveComponent动态实例化,如下:

<component :is="resolveComponent(item.component)" v-for="(item,index) in messageList":key="index" :message="item"></component>


<script setup>
import {resolveComponent} from "vue";
import ComA "./ComponentA";
import ComB "./ComponentB";

</script>

在本人电脑上尝试无效果。