yii控制台命令需继承yii\console\controller、置于@commands/目录、命名规范、动作方法为public actionxxx(),参数选项须显式声明,定时任务用绝对路径crontab,配置与web分离。

Yii 控制台命令不是“配个入口就能跑”,它依赖明确的类路径、继承关系和 CLI 环境约束;直接复制 web 控制器代码到 commands/ 下,90% 会报 Unknown command 或 Class not found。
console 控制器必须继承 yii\console\Controller
这是最常踩的坑:用 yii\web\Controller 或裸写类,命令根本不会被识别。
- 控制器文件必须放在
@app/commands/目录下(如HelloController.php) - 类名必须匹配文件名,且以
Controller结尾:HelloController→HelloController.php - 类必须
extends yii\console\Controller,不能是yii\base\Controller或其他基类 - 每个可执行动作必须是
public function actionXXX()形式,比如actionSend()对应命令php yii hello/send
prompt() 和 confirm() 只在 TTY 环境生效
它们底层调用 fgets(STDIN),一旦 stdin 被重定向(| cat)、管道接管或运行在 CI 中,就会跳过、卡住或返回空值。
- 务必先检查
$this->isInteractive,非交互时应跳过或 fallback 到参数判断 - CI/自动化场景必须加
--force类开关,并在 action 逻辑里用$this->options['force'] ?? false替代confirm() - 提示文字不显示?大概率是 stdout 缓冲问题,改用
$this->stdout($text . ' ')替代echo - Windows 下中文乱码需确保终端执行
chcp 65001,PHP 文件保存为 UTF-8 无 BOM
参数和选项必须显式声明才能安全使用
Yii 不会自动把所有 --xxx 注入到 action 方法参数里——没声明的选项会被忽略,声明了但没接收则直接报错 Unknown option。
- 在控制器类中定义
public $options = ['env', 'force', 'days']; - action 方法签名要严格对应:
public function actionRun($days = 30, $env = 'prod') - 位置参数按顺序绑定,选项参数靠名字匹配,混用时位置参数必须写在选项前面:
php yii clean-log/run 60 --env=staging - 别依赖未声明的
$this->getOptions(),它只返回已声明且被解析的键值对
定时任务必须用系统 crontab + 绝对路径
Yii 没有内置调度器,任何「自动执行」都得靠外部触发。crontab 写错一行,任务就静默失败。
- crontab 条目必须带完整路径:
cd /var/www/myapp && /usr/bin/php yii clean-log/run --days=90 > /dev/null 2>&1 - 绝对不要写
php yii ...,要用which php查真实路径,尤其 Docker 或 MAMP 环境 - 避免用
*/5 * * * *这种表达式测试——它在某些 cron 实现里行为不一致,先用15 * * * *验证流程 - console 配置(如
db、params)和 web 是分离的,确保config/console.php里已正确配置数据库和日志通道
真正上线前最容易被忽略的是环境一致性:console 应用加载的是 config/console.php,不是 web.php;Yii::$app->db 可能连的是测试库,而你正在删生产日志。











