25
2010

ThinkPHP中设置Cookie的方法,cookie方法bug

   ThinkPHP中内置的cookie方法无效的解决方案,ThinkPHP内置Cookie类只是对setcookie的简单封装,但使用起来却老是无效。这个问题纠结了我一整天终于找到了原因。

以下现象出现在ThinkPHP 2.0中。

故障现象1:使用cookie能发送cookie到浏览器,但是设置有效时间没用。代码:cookie('c_name','c_data',3600);该条语句发送一个名称为c_name,内容为c_data,有效时间为1天的Cookie到浏览器。结果cookie能发送但是过期时间总是“当会话结束时”,百思不得其解,看下cookie函数的源码(ThinkPHP/Common/functions.php)834行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function cookie($name,$value='',$option=null)
{
    // 默认设置
    $config = array(
        'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀
        'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间
        'path'   => C('COOKIE_PATH'),   // cookie 保存路径
        'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名
    );
    // 参数设置(会覆盖黙认设置)
    if (!empty($option)) {
        if (is_numeric($option))
            $option = array('expire'=>$option);
        elseif( is_string($option) )
            parse_str($option,$option);
        array_merge($config,array_change_key_case($option));
    }
    // 清除指定前缀的所有cookie
    if (is_null($name)) {
       if (empty($_COOKIE)) return;
       // 要删除的cookie前缀,不指定则删除config设置的指定前缀
       $prefix = empty($value)? $config['prefix'] : $value;
       if (!empty($prefix))// 如果前缀为空字符串将不作处理直接返回
       {
           foreach($_COOKIE as $key=>$val) {
               if (0 === stripos($key,$prefix)){
                    setcookie($_COOKIE[$key],'',time()-3600,$config['path'],$config['domain']);
                    unset($_COOKIE[$key]);
               }
           }
       }
       return;
    }
    $name = $config['prefix'].$name;
    if (''===$value){
        return isset($_COOKIE[$name]) ? unserialize($_COOKIE[$name]) : null;// 获取指定Cookie
    }else {
        if (is_null($value)) {
            setcookie($name,'',time()-3600,$config['path'],$config['domain']);
            unset($_COOKIE[$name]);// 删除指定cookie
        }else {
            // 设置cookie
            $expire = !empty($config['expire'])? time()+ intval($config['expire']):0;
            setcookie($name,serialize($value),$expire,$config['path'],$config['domain']);
            $_COOKIE[$name] = serialize($value);
        }
    }
}

    array_merge($config,array_change_key_case($option)); 这条语句就是用来实现设置参数覆盖黙认设置。不过array_merge($array1,$array2);返回的独立的数据集合并没有更新$array1或$arrary2;所以单array_merge($config,array_change_key_case($option));是无法改变$config默认设置的。应该改成

$config = array_merge($config,array_change_key_case($option));

故障现象2:$_COOKIE['c_name'] 可以显示出结果,但是浏览器中并没有cookie数据。
这个现象也比较烦躁,ThinkPHP中Cookie类仅对setcookie方法进行了简单的封装,所以问题没处在ThinkPHP,百度了下大都说setcookie之前不能有任何输出以及BOM头信息。

7 条评论 + 发条评论

  • 不知道现在COOKIE类 有没有接解决好这个问题

    • SVN中有解决的。

  • 呵呵,刚才在百度里面搜索thinkphp cookie到你这儿来了,发现你也是PHP爱好者,并且也熟悉thinkphp,感觉你这不错,呵呵 ,特留一个脚印。
    我的博客是自己用thinkphp写的,有空多交流

  • http://www.wuleilei.com
    差点忘了留网址了[face24]

    • 呵呵,谢谢来访。

  • http://www.piaoboyizu.com 嘿嘿第一次见你回访,问候一下。

    • 呵呵 欢迎笨笨,哪里是第一次哦 我可是一只有拜访的哦 只是没好意思打扰的。呵呵

发条评论

*

*