ThinkPHP中Cookie::set()第三个参数必须传整数秒而非时间戳,如86400表示1天;传time()+86400会导致立即失效;数组方式需用'expire'键,且门面不自动合并配置。

Cookie::set() 第三个参数必须是整数秒,不是时间戳
传 time() + 86400 会直接导致 Cookie 立即过期或行为异常——ThinkPHP 内部自动处理为绝对时间戳,你只需传纯秒数。比如想设 30 天,就写 2592000,别加 time()。
数组参数方式更可控,但 key 名必须准确
用数组传参时,有效期字段名是 expire,不是 maxAge、timeout 或 ttl。其他常用键包括:path(建议固定为 '/')、domain(跨子域需带前导点,如 '.example.com')、secure 和 httponly(生产环境应设为 true)。
-
expire:单位是秒,0 表示会话级(关浏览器即丢) -
path:不填默认'/',但显式写上更稳妥 -
domain:填空字符串''表示仅当前主机,填'.example.com'才能被子域共享 -
secure:HTTP 站点设false会静默失败;HTTPS 站点必须为true,否则浏览器可能拒收
别混用助手函数和门面,配置项不会自动合并
用 cookie('lang', 'zh-cn', 86400) 和 Cookie::set('lang', 'zh-cn', ['expire'=>86400]) 效果看似一样,但前者会读取 config/cookie.php 中的全局 COOKIE_PREFIX、COOKIE_DOMAIN 等配置,后者则完全忽略——除非你在数组里手动写全。
所以:如果项目已配了 'domain' => '.example.com',用助手函数就能省事;用门面就必须自己补全,否则跨子域语言切换会失效。
立即学习“PHP免费学习笔记(深入)”;
永久 Cookie 不是“永不过期”,而是 10 年有效期
Cookie::forever('lang', 'en-us') 底层其实是设了 315360000 秒(10 年),并非真正永久。它不读配置、不支持自定义参数,且无法与 httponly 或 secure 混用。真要长期有效又安全,老老实实传数组:
Cookie::set('lang', 'en-us', [
'expire' => 2592000, // 30 天
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true
]);
多语言场景下,expire 设太短(比如 1 小时)会导致用户刚切完语言就回退,设太长(如 10 年)又不利于合规审计——30 天是兼顾体验与 GDPR/CCPA 的常见折中点。



















