命令行
StartMVC 内置一套轻量命令行工具,用于查看路由、生成控制器与模型骨架、清理编译缓存与历史日志。入口文件是项目根目录下的 startmvc.php,Web 请求仍走 public/index.php,两者互不影响——命令行入口只允许在命令行下运行,通过浏览器访问会直接返回 403。
入口文件未命名为 startmvc,是因为项目根目录已存在同名的 startmvc/ 框架目录:Windows 下同名的文件与目录无法共存。
php startmvc.php # 列出全部命令
php startmvc.php route:list # 查看路由表与编译缓存状态
php startmvc.php make:controller home/Article # 生成控制器骨架
php startmvc.php make:model home/Article # 生成模型骨架
php startmvc.php cache:clear # 清理编译缓存
php startmvc.php log:clear # 清理历史日志(默认保留最近 30 天)
查看全部命令
不带参数,或使用 list / help,都会列出全部命令(含当前框架版本号):
StartMVC 命令行工具 v3.1.1
+-----------------+-----------------------------------------------------------+
| 命令 | 说明 |
+-----------------+-----------------------------------------------------------+
| route:list | 列出已注册的全部路由,并显示编译缓存状态 |
| make:controller | 生成控制器骨架,用法:make:controller [模块/]名称 |
| make:model | 生成模型骨架,用法:make:model [模块/]名称 [--table=表名] |
| cache:clear | 清理路由编译缓存与模板编译缓存 |
| log:clear | 清理历史日志文件(默认保留最近 30 天) |
+-----------------+-----------------------------------------------------------+
用法:php startmvc.php <命令> [参数...] [--选项=值]
输入不存在的命令时会提示「未知命令:xxx」并同样列出命令表,进程退出码为 1,便于在脚本或 CI 中判断执行结果。
参数写法
参数写在命令之后,支持三种形式:
--键=值:传给命令的选项,例如--table=news--开关:不带等号即为布尔真,例如--force- 其余参数按出现顺序作为位置参数读取,例如
home/Article
查看路由:route:list
route:list 打印已加载的路由表,并标注每条路由的类型:static(不含占位符,走哈希精确匹配)、dynamic(含占位符,注册时已编译为正则)、raw(原生正则)。中间件列显示该路由绑定的中间件别名或类名,未绑定时为 -。
命令末尾会一并给出编译缓存的当前状态。修改路由配置后先跑一次,可立即确认路由是否按预期注册、缓存是否已自动失效重建。
路由列表
+--------+---------+---------------------+----------------------+--------+
| METHOD | 类型 | URI | 目标 | 中间件 |
+--------+---------+---------------------+----------------------+--------+
| ANY | static | /about | home/index/about | - |
| ANY | raw | /^archive\/(\d{4})$ | home/post/archive/$1 | - |
| GET | static | /article | Home/Article/index | - |
| GET | dynamic | /article/:id | Home/Article/detail | log |
| POST | static | /login | Home/User/login | - |
+--------+---------+---------------------+----------------------+--------+
共 5 条路由(static=精确匹配,dynamic=占位符,raw=原生正则)
编译缓存:已生成 runtime/cache/routes.php(1.3 KB)
失效依据:config/route.php 的修改时间 + 框架版本号;可用 cache:clear 手动清理
两点说明:数组配置(旧版写法)不区分 HTTP 方法,因此 METHOD 列显示为 ANY;路由目标是闭包时,目标列显示为 Closure。若项目中尚未定义任何自定义路由,会提示所有请求都走「模块/控制器/方法」自动解析。
生成控制器:make:controller
用法 make:controller [模块/]名称,省略模块时取 config/common.php 中的 default_module 配置。生成的文件位于 app/模块/controller/:
php startmvc.php make:controller home/Article
控制器已生成:app/home/controller/ArticleController.php
类名 :app\home\controller\ArticleController
默认视图:app/home/view/article/index.php
提示:模板路径由「模块/控制器/方法」推导,控制器名全小写即为视图目录名
名称按框架既有规则归一化:先整体转为小写,再把横线、下划线分隔的每一段首字母大写,并在末尾补 Controller 后缀——这与 Router::convertController() 的转换规则完全一致。因此 article-type、article_type 都会生成 ArticleTypeController.php;而传入已是大驼峰的 ArticleType 会先被压平为小写,得到 ArticletypeController.php——建议命令行里统一使用全小写或横线、下划线写法。
这条规则必须与路由保持一致:若按输入原样保留大小写生成 ArticleTypeController.php,Windows 下能正常运行(文件系统不区分大小写),但 Linux 下自动载入会找不到文件——PHP 类名不区分大小写,文件名区分。
目标文件已存在时不会覆盖,会给出提示并返回失败;确认要覆盖时追加 --force。
生成模型:make:model
用法 make:model [模块/]名称 [--table=表名] [--force],生成的文件位于 app/模块/model/,类名按上述规则归一化并补 Model 后缀:
php startmvc.php make:model home/Article # 表名按类名推断为 article
php startmvc.php make:model home/Article --table=news # 指定表名 news
模型已生成:app/home/model/ArticleModel.php
类名 :app\home\model\ArticleModel
表名 :article(可在模型里修改 $table,或用 --table=表名 重新指定)
不传 --table 时,表名由类名转为下划线小写推断(ArticleType → article_type),写入生成骨架的 $table 属性,后续可直接在该属性上调整。
清理缓存:cache:clear
清理两类编译缓存:路由编译缓存 runtime/cache/routes.php,以及模板编译产物(runtime/temp/模块/ 下的文件)。两者都会在下次请求时自动重建。
清理编译缓存
已删除 runtime/cache/routes.php
跳过 runtime/temp/*/(没有模板编译产物)
缓存已清理,共删除 1 个文件
若存在模板编译产物,会多出一行「已清空 runtime/temp/*/ 下的模板编译产物(N 个文件)」。命令是幂等的,没有缓存可清时输出「没有需要清理的缓存」。
删除范围有明确边界:只清理各模块子目录内的编译产物,不会触碰 runtime/temp/ 根目录下的文件,你自己放在那里的脚本不会被误删。
开发中遇到「改了路由却未生效」时也可以用它:缓存失效依据是文件修改时间(秒级精度),刚改完立刻刷新可能仍读到旧缓存,执行本命令可强制重建。
清理日志:log:clear
日志按天轮转,但不会自动清理 —— 这是刻意的:在写入路径里静默删除用户文件,风险远大于收益。假如改成按「只保留最近 N 个文件」自动清理,一旦业务代码开始写 info/debug 级别的日志,日志文件数量会迅速膨胀,30 个文件可能只覆盖三四天,历史日志就被无声抹掉了。所以清理做成显式动作,由本命令手动执行,默认保留最近 30 天。
php startmvc.php log:clear # 保留最近 30 天
php startmvc.php log:clear --keep-days=7 # 保留最近 7 天
php startmvc.php log:clear --keep-days=0 # 全部清空(等价于 --all)
php startmvc.php log:clear --all # 全部清空
php startmvc.php log:clear --dry-run # 只预览,不删除
建议先预览、确认无误再去掉 --dry-run:
清理历史日志
目录 runtime/logs
策略 保留最近 30 天
模式 预览,不会真正删除(--dry-run)
待删除 2025-10-29_error.log 4.5 KB
待删除 2026-03-06_error.log 20 KB
待删除 2026-07-17_error.log 3.6 KB
待删除 2026-07-18_error.log 8.2 KB
待删除 2026-07-26_error.log 3.6 KB
待删除 2026-07-27_error.log 10 KB
待删除 2026-07-28_error.log 12.7 KB
待删除 2026-07-29_error.log 929 B
预览:8 个文件将被删除,可释放 63.5 KB
去掉 --dry-run 即执行删除
真正执行时,逐个文件输出「已删除 文件名 大小」,结尾汇总「已删除 N 个日志文件,释放 X」,并提示保留了其余多少个文件。
三个选项:
--keep-days=N:保留最近 N 天(含今天),传0等价于--all。非数字会被纠偏为默认值 30 并给出提示;上限 3650 天,超过按上限处理。--all:清空全部日志文件。--dry-run:只列出将被删除的文件与可释放空间,不做任何删除。
删除范围有明确边界:只在日志目录的「当层」操作,不递归子目录、不删除目录本身;只删文件名形如 2026-09-19.log 或 2026-09-19_error.log 的文件,你放在同一目录下的其他文件一律不碰;符号链接一律跳过,避免顺着链接删到日志目录之外。某个文件删不掉(被占用或权限不足)只记一条警告并继续,最后进程退出码为 1,便于在脚本里判断。
日志目录取自 Logger::getPath(),与写入方共用同一套路径解析逻辑 —— 在 config/log.php 里改了 path,清理时同样会跟着走。
自定义命令
命令类继承 startmvc\core\console\Command,声明 $name、$description 并实现 handle() 即可:
namespace app\command;
use startmvc\core\console\Command;
class Hello extends Command
{
protected $name = 'demo:hello';
protected $description = '示例命令:输出问候语';
protected function handle(array $args)
{
$who = $this->option('name', 'StartMVC');
$this->info('你好,' . $who);
return true; // 返回 false 时进程退出码为 1
}
}
基类已提供命令所需的全部能力,无需自己解析 $argv:arg(0) 取位置参数、option('key', $default) 取选项、hasOption('force') 判断开关;输出用 line()、info()、warn()、error()、muted()、table(),排版由内核统一处理——表格按显示宽度对齐(中文按全角两列计算,不会错位),终端不支持颜色时自动降级为纯文本,因此输出重定向到文件时不会混入转义字符;另有 studly()、snake()、rootPath()、writeFile() 等常用工具方法。
命令类放在可被自动载入的目录即可(类名即路径,例如 app/command/Hello.php 对应 app\command\Hello),随后在入口文件 startmvc.php 中注册:
$console = new \startmvc\core\console\Console(ROOT_PATH);
$console->registerDefaults(); // 注册框架内置命令
$console->register('demo:hello', \app\command\Hello::class); // 注册自定义命令
exit($console->run(isset($argv) ? $argv : []));
注册后即可用 php startmvc.php demo:hello --name=World 执行,命令说明会同时出现在命令列表中。