codeigniter定时任务必须通过cli入口执行:ci3需用index.php+控制器方法调用并校验is_cli_request(),ci4必须继承basecommand类并用spark运行;crontab须用绝对路径、显式cd、重定向日志,禁用curl/wget触发。

CodeIgniter 定时任务不能靠 curl 或浏览器访问触发,必须走 CLI 入口;否则 is_cli_request() 失败、数据库连不上、服务未加载——90% 的失败都卡在这一步。
CI3 怎么写可被 crontab 调用的控制器
CI3 没有 spark 命令,得靠 index.php + 控制器方法组合调用。关键不是“能不能跑”,而是“能不能在 crontab 里稳定跑”。
- 控制器构造函数里必须加拦截:
if (!$this->input->is_cli_request()) { show_error('CLI only'); } - 参数通过
$this->uri->segment(3)获取(比如php index.php cron clean_temp_files 7中的7),别用$_GET(CLI 下不可用)或裸$argv(易错且不兼容) -
is_cli()函数依赖PHP_SAPI === 'cli'或defined('STDIN'),确保没被覆盖或误判 - 模型和库照常加载,但避免在 CLI 中调用
redirect()、set_cookie()这类 Web 专属功能
CI4 的 CLI 命令必须继承 BaseCommand 类
CI4 不允许“裸脚本”执行,所有定时逻辑必须封装成 app/Commands/xxxCommand.php,否则 spark 根本看不到它。
- 类名必须以
Command结尾(如SendNewsletterCommand),否则spark list不显示 - 必须设置
$this->group和$this->description,不然命令列表里只有名字、没有说明 - 参数统一用
$this->getArgument('days')或$this->getOption('force'),别碰$argv或$_SERVER['argv'] - 输出必须用
$this->info()/$this->error(),echo会破坏颜色、换行,某些终端下还会截断
crontab 里调用失败的 90% 原因是路径和环境变量不对
本地手动执行成功 ≠ crontab 能跑通。crontab 使用最小环境,不读你的 ~/.bashrc,也不继承当前 shell 的 PATH 和工作目录。
- crontab 条目必须用绝对路径:
/usr/bin/php /var/www/myapp/index.php cron daily_backup(CI3)或/usr/bin/php /var/www/myapp/spark send:newsletter(CI4) - 推荐显式
cd切工作目录:0 2 * * * cd /var/www/myapp && /usr/bin/php spark cleanup:logs > /var/log/myapp-cron.log 2>&1 - 别用
~或相对路径,crontab -e里写什么就是什么 - 日志重定向必须写全:
> /var/log/myapp-cron.log 2>&1,否则失败了连错误都看不到
最易被忽略的是 PHP CLI 环境与 Web 环境不一致:扩展(如 pdo_mysql)、版本、open_basedir 限制、甚至 date.timezone 都可能不同。调试前先确认 crontab 里用的 php -v 和 php -m 输出跟手动执行是否一致。











