codeigniter原生不支持laravel风格队列,定时任务必须通过cli+crontab实现;ci3需控制器显式拦截非cli请求并用uri->segment取参,ci4必须继承basecommand类、用spark运行,crontab调用须用绝对路径、cd切目录并重定向日志。

CodeIgniter 原生不支持 Laravel 风格的 queue:work 或后台长运行消费者,定时任务只能走 CLI + crontab 组合——这不是缺陷,而是设计取舍。你没法靠浏览器访问或 php script.php 触发任务,否则 is_cli() 失败、数据库连不上、服务未加载,90% 的失败都卡在这一步。
CI3 中 CLI 控制器必须显式拦截非 CLI 请求
CI3 没有命令注册机制,全靠控制器方法暴露为可执行入口。但框架不会自动拒绝 Web 访问,得你自己拦住:
- 构造函数里加
if (!$this->input->is_cli_request()) { show_error('CLI only'); } - 别依赖
$_GET或$_SERVER['argv']:CLI 下$_GET为空,$argv不稳定;用$this->uri->segment(3)取第一个参数,segment(4)取第二个,以此类推 - 方法签名里的默认参数(如
public function clean_temp_files($days = 7))只在没传参时生效;crontab 调用时建议显式传值,避免歧义
CI4 必须用 spark 命令 + BaseCommand 类封装
CI4 彻底放弃“控制器即命令”的做法,所有 CLI 逻辑必须继承 CodeIgniter\Commands\BaseCommand,否则 spark list 根本看不到它:
- 文件路径必须是
app/Commands/CronBackupCommand.php,类名必须以Command结尾 - 必须设置
$this->group = 'cron';和$this->description = 'Run daily database backup';,否则spark list只显示无意义的命令名 - 参数统一走
$this->getArgument('days')或$this->getOption('force'),别碰原始$argv - 输出必须用
$this->info()/$this->error(),直接echo会破坏终端颜色和换行,某些环境下还会截断日志
crontab 调用失败的主因永远是环境变量和路径
你在终端手动跑通了 /usr/bin/php /var/www/app/index.php cron daily_backup,不代表 crontab 能跑通。crontab 使用极简 shell 环境,PATH、当前目录、PHP 解释器路径都不同:
- crontab 条目必须写绝对路径:
/usr/local/bin/php而不是php;查实际路径用which php - 加
cd /var/www/app &&切到应用根目录,否则相对路径(如./uploads/temp)会失效 - 重定向日志:末尾加
> /var/log/ci-cron.log 2>&1,否则出错时完全无迹可查 - 别用
wget或curl触发 URL 来“模拟”定时任务——这绕过 CLI 环境,is_cli()返回 false,模型和库无法加载
想实现队列语义?得自己加状态表 + 行锁
CI 没有 Redis 队列,但你可以用数据库表模拟轻量级任务队列。关键不在“有没有”,而在“怎么防并发”:
- 建表字段至少含
status ENUM('pending','running','done','failed')、locked_at DATETIME NULL、payload TEXT - 每次 CLI 执行时,用
SELECT ... FOR UPDATE或带WHERE status = 'pending' AND locked_at IS NULL LIMIT 1更新,再立即UPDATE SET locked_at = NOW(), status = 'running' - 执行完更新
status和finished_at;若任务崩溃,靠locked_at超时(比如 30 分钟)识别僵尸任务并重置 - Cron 每分钟调一次这个命令,就相当于一个极简轮询消费者——它不快,但足够稳
最常被忽略的是:CI 的定时任务本质是「单次执行脚本」,不是「持续监听的进程」。任何试图用 exec() 在 Web 请求里后台启动 CLI、又不管理 PID 和信号的做法,迟早遇到僵尸进程或重复触发。稳住节奏,靠 crontab 控制频率,靠数据库控制状态,比强行套用其他框架的队列模型更贴合 CI 的设计哲学。











