set_cookie() 是 CodeIgniter Cookie Helper 的全局函数,需先加载 helper;$this->input->set_cookie() 是 Input 类方法,参数顺序固定且更面向对象,两者底层逻辑相同但调用方式和参数结构不同。

set_cookie() 是什么,和 $this->input->set_cookie() 有啥区别
set_cookie() 是 CodeIgniter 的 Cookie Helper 提供的全局函数,必须先 $this->load->helper('cookie') 才能用;而 $this->input->set_cookie() 是 Input 类的方法,底层其实也调用了同一个逻辑,但更“面向对象”一点。两者参数结构不同:前者接受数组或独立参数,后者强制按 name, value, expire, domain, path, prefix, secure, httponly 顺序传参。
常见错误现象:混用两种写法却没加载对应依赖——比如直接调 set_cookie() 却忘了 load->helper('cookie'),结果静默失败,浏览器里根本看不到 cookie。
- 推荐统一用
set_cookie()数组形式,语义清晰、不易错位 - 如果已在构造函数自动加载 helper,就别重复
load->helper -
$this->input->set_cookie()在较老版本 CI(如 2.x)中更常见,CI 3+ 更倾向 helper 函数
set_cookie() 数组参数怎么填才不踩坑
最稳妥的方式是传关联数组,把所有关键字段显式写出,尤其注意 expire 是「秒数」而非时间戳,domain 和 path 留空时默认为当前域名和 /,但一旦指定就必须带前导斜杠(path => '/' 合法,path => '' 或 path => '\/' 会失效)。
容易踩的坑:expire 设成 3600 表示 1 小时后过期,不是“1 小时后的时间戳”;设成 0 表示会话级 cookie(关浏览器即丢),设负数则等同于删除。
-
name和value必填,其他可选 -
secure => true时,cookie 只通过 HTTPS 传输;本地开发用 HTTP 却设了它,cookie 就不会写入 -
httponly => true能防 XSS 读取,但 JS 就拿不到——若你前端要读这个 cookie,就得设false,且确认 config 中没全局锁死cookie_httponly = TRUE
为什么 set_cookie() 写了却看不到,或者 get_cookie() 返回 NULL
不是代码没跑,而是 cookie 没发到浏览器,或发了但被拦截/忽略。典型原因有三:响应头已发送(比如前面 echo 过、开启了输出缓冲但没 flush)、域名不匹配(domain 设太宽或太窄)、路径不一致(写在 /admin/ 路径下,却在 /api/ 下读)。
调试建议:用浏览器开发者工具的 Application → Cookies 面板,看 domain/path/expiry 是否符合预期;再检查 Network → Response Headers 里有没有 Set-Cookie: 字段。
- 确保 controller 方法里没有提前
echo、print_r或开启output_buffering后未清理 - CI 默认对 cookie 值做 XSS 过滤,如果值含特殊字符(如 JSON 字符串),可能被清空——可传
xss_clean => FALSE给get_cookie(),但务必自己做校验 -
get_cookie('xxx')返回的是过滤后的值;想绕过过滤直接读原始值,得用$_COOKIE['xxx'](仅限模型或非安全敏感场景)
delete_cookie() 怎么删才真正生效
delete_cookie() 不是“清空值”,而是发一个 Max-Age=0 的 Set-Cookie 头,让浏览器立刻丢弃。所以它必须和当初设置时的 domain、path、prefix 完全一致,否则删的是另一个 cookie。
常见错误:当初用 set_cookie(['name'=>'token', 'domain'=>'.example.com']) 设置,删时却只写 delete_cookie('token'),结果删不掉——因为 domain 不匹配。
- 删之前最好先
var_dump(get_cookie('token'))确认它还存在 - 安全起见,删的时候显式带上相同
domain和path:delete_cookie(['name'=>'token', 'domain'=>'.example.com', 'path'=>'/']) - 如果用
set_cookie()设了prefix(如'prefix'=>'ci_'),删时 name 必须带前缀,或同样传prefix参数










