CI4.7.1中spark是CLI唯一合法入口,自定义命令需满足:类继承CodeIgniter\CLI\BaseCommand、置于app/Commands/下、类名以Command结尾、设置非空group和description、命名空间为App\Commands;参数须用getArgument()/getOption()获取,crontab调用需用绝对路径、cd切换工作目录并确保writable目录权限正确。

CI4.7.1 的 spark 不是可选插件,而是 CLI 任务的唯一合法入口——任何绕过它的调用(比如直接 php app/Commands/SendEmail.php)都会因服务容器未初始化而报 Class 'Config\Services' not found。
为什么 spark 命令不显示你的自定义命令
根本原因不是代码写错,而是类定义或路径没满足框架识别规则:
- 类必须继承
CodeIgniter\CLI\BaseCommand,且文件放在app/Commands/下(不能放app/Commands/Tools/子目录,除非你改了自动加载配置) - 类名必须以
Command结尾,例如SendNewsletterCommand;SendNewsletter或NewsletterSender都不会被扫描到 -
$this->group和$this->description属性必须设置非空字符串,否则spark list完全忽略该命令 - 如果用了命名空间,必须是
App\Commands(默认),其他命名空间需手动在app/Config/Autoload.php中注册 PSR-4 映射
如何安全传参并避免 getArgument() 报 Notice
$this->getArgument() 和 $this->getOption() 是唯一推荐方式,但它们对缺失参数很敏感:
- 定义
protected $arguments = ['type' => '缓存类型,默认 all'];后,spark app:clear-cache db才能取到$this->getArgument('type');若没传值,getArgument()返回null,不是空字符串 - 选项必须带前缀:定义
--force,调用时必须写spark app:clear-cache --force,-f简写不支持,除非你手动实现别名逻辑 - 不要用
$argv或$_SERVER['argv']—— CLI 环境下这些可能被 spark 入口重写,行为不可靠 - 调试时可用
$this->info(print_r($params, true));查看实际传入的索引数组结构
crontab 调用 spark 总失败?检查这三点
本地能跑 ≠ crontab 能跑,环境隔离是最大陷阱:
- crontab 不读
~/.bashrc或~/.zshrc,所以spark命令找不到。必须用绝对路径:/usr/bin/php /var/www/myapp/spark send:news,其中/usr/bin/php要和which php输出一致 - 工作目录默认是
/root(非项目根目录),导致APPPATH解析错误、日志写入失败、.env 加载异常。解决方案是加cd /var/www/myapp &&前缀,或在命令开头显式设置CWD - PHP CLI 模式可能启用了不同扩展(比如没开
pdo_mysql),运行php -m | grep pdo和php -i | grep 'Loaded Configuration File'核对配置文件路径,确保与 Web 环境一致
最常被忽略的是 .env 文件中 CI_ENVIRONMENT = development 在 CLI 下依然生效——这意味着日志会写入 writable/logs/,而 crontab 进程可能没有该目录写权限,结果命令静默失败。务必确认 writable/ 及其子目录属主为运行 crontab 的用户(如 www-data 或 root),且权限为 755 或 775。


















