使用cookie定制用户UI

2005年,国外一家网站推用了第三方个人门户网站服务,友好的界面,用户体验,无不给浏览者带来了心跳加速的感觉。这个网站就是 www.netvibes.com。随后,国内出现了类似站点:www.okrss.com及my.potu.com。国内的这两家网站可以说几乎是完整的拿下了netvibes的js代码,用以最基础的开发。笔者通过对www.netvibes.com网站的结构思想分析后,本着学习的一种心态,基于netvibes网站的几个底层JS,尝试着写了 www.gbrss.com [中文RSS]网站。下面就以本网站中对区块移动时的用户UI存储做下实例分析。

注:本站在写作过程中,得到了 喜悦国际村 村民 shelly,奶瓶,Q版安东尼 的大力支持,在此先感谢诸位付出的心血。

为了节省系统开支,经过分析,我决定抛弃以上三网站的用户UI存储方法,使用客户端cookie进行用户UI的保存及处理。

首先我预定义了默认的用户UI界面,为一个基础数组,结构如下:

$DEFAULT_UI[’header’]  :用户自定义头部

$DEFAULT_UI['header'] = array(
'title' => "本页可任意拖曳修改,赶快注册中文RSS(<a href="http://www.gbrss.com/">www.gbRss.com</a>)网,拥有自己新闻网站",
'userFeeds' => '0',
'featuredFeeds' => '1688816888',
'defaultFeeds' => '1688916889',
);
$DEFAULT_UI[’body’] :用户区块

$DEFAULT_UI['body'] =  array(
  'id'=>GetRandCode(10),
  'column'=>1,
  'name'=>'RssReader',
  'status'=>1,
  'title'=>'',
  'data'=>array('feedId'=>1,'nbTitle'=>'','color'=>'#fff','openOutside'=>0)
),
.............
及$DEFAULT_UI[’feeds’],此数组由程序动态生成,主要存放用户UI界面区块中的RSS源及用户自定义CHANNEL。

分别与cookie中的UI_HEADER,UI_MOD,UI_FEEDS一一对应。而用户的UI_CHANNELS与默认无关,只有用户定制了之后,由相应的程序生成。

当我开始使用cookie存放经过序列化的以上资料时,却不得不面对一个事实:同域最多支持20个cookie,而单个cookie最大的许可值是4k。在这种情况下,我面临的是 UI_MODULES 过多,UI_FEEDS过大。在用户自定义区块超过20之后,它们似乎就能令cookie罢工。我不得不停下手中的程序,开始进行思索如何解决这个问题。经过与喜悦国际村几个村友讨论之后,决定使用压缩数据来解决这个问题:利用php自带函数

gzcompress、gzuncompress
来解决这个问题。我们已经做过测试,在用户定制区块 20 左右时,未经压缩的 UI_MODULES 几乎已经达到了cookie最大的允许值,达到 3.5k+,经过压缩后,在 2.k- 以内。这个测试让我们惊喜不已,于是在项目开发过程中,就定下来使用这种方案在cookie中保存大容量的USER_UI。

经过分析netvibes中的js代码,我们很容易的得到一个结论:用户区块的移动,是通过js进行移动的同时,利用ajax异步发出了一个请求信号,目标文件是 saveUserData.php。根据order的参数分析,用户UI界面的纵、横身排序是通过”:”进行横向排序,通过”,”进行纵向排序的。如,当请求的order=1,2,3:4,5,6,7:8时,用户UI如下:
——————————————————
|        1            |            4              |          8          |
|        2            |            5              |                      |
|        3            |            6              |                      |
|                      |            7              |                      |
——————————————————
或许你会发现,在第三列中,只有一个区块ID为8的,而下面三行都没有任何内容进行填充。同时,你也会发现,在第一列的第四行,也是如此。是的,这不是我的错,这是我故意以这种形式来说明问题的。值得说明的是,在用户UI中,所有的区块都可以为空的。比如可能第二列无任何内容,或者第三列。那么我们就很够能轻松的通过order的状态来进行数据重组了,我把压/解的代码写在了类文件saveUserData.php中,此文件还包含了通过order指令重排数据结构的一个方法。如下代码所示:

saveUserData.php
[php]  
...............
  
function __set_order ()
{
  $order = trim($_POST['order']);
  if( $this->cookie['user'] == 'logined' )
  {
   /**
    * 注册用户桌面
   */
   $old_ui = $this->cookie['REG_UI_MOD'] ? $this->__decode( $this->cookie['REG_UI_MOD'] ) : '' ;
   $new_ui = $this->__orders( $old_ui,$order );
   $new_ui = $this->__encode( $new_ui );
   $UI_MOD_TYPE = "REG_UI_MOD";
  }
  else
  {
   /**
    * 匿名用户桌面
   */
   $old_ui = $this->cookie['UI_MOD'] ? $this->__decode( $this->cookie['UI_MOD'] ) : '' ;
   $new_ui = $this->__orders( $old_ui,$order );
   $new_ui = $this->__encode( $new_ui );
   $UI_MOD_TYPE = "UI_MOD";
  }
  
  if( $this->setCookies->makeCookie( $UI_MOD_TYPE ,$new_ui, $this->cookietime ) )
  {
   echo "\"order\",true";
  }
  else
  {
   echo "\"order\",false";
  }
  
function __encode ($str)
{
  $ser = serialize($str);
  $gz = gzcompress($ser);
  $baseen = base64_encode($gz);
  return $baseen;
}
  
function __decode ($str)
{
  $basede = base64_decode($str);
  $ungz = gzuncompress($basede);
  $unser = unserialize($ungz);
  return $unser;
}
  
function __orders ( $UI,$order )
{
  foreach( (array)$UI as $key=>$val )
  {
   $id = $val['id'];
   unset($val['id']);
   unset($val['column']);
   $querys[$id] = $val;
  }
  
  $order = explode(":",$order);
  $result = array();
  foreach ( (array)$order as $place=>$space )
  {
   $space = explode(",",$space);
   $place++;
   foreach( (array)$space as $block )
   {
    if(!$block) break;
    foreach( (array)$querys["$block"] as $key=>$val )
    {
     $data['id'] = $block;
     $data['column'] = $place;
     $data[$key] = $val;
    }
    array_push($result,$data);
   }
  }
  return $result;
}
  
.............
[/php]  
通过以上代码所示,我们通过分析流程,很轻松的就把数据重组后存储到cookie中。至于如何取得cookie,那是下篇文章的内容了。近期我会剖析整个 www.gbrss.com 网站架构过程。把心得体会写出来与大家共享讨论。

作者:无喱头
出处:www.phpsoho.com blog.phpsoho.com
籍贯:喜悦国际村
转载请注明出处
顶一下,楼主的签名站不错。
喱头..蛮酷的!!
逛啦 小游戏:http://www.guangla.com
我是奶哥~
听歌
DLAPK
发贴时竟然不知道有PHP标签可选。。。。
超过二十分钟也无法再进行编辑,所以比较郁闷。。。
先开源再讲解(源码和教材一起打包),可能好点?

这样分开讲太难收集分散了.....
恩,不错,空了学习
手机软件
软吧[Ruan8.com]中国免费手机软件第一门户!
强...........顶了.
不过就是网站慢了点.我这里半天还没打开...
期待网站架构.....
正着念php,反着念php.
支持,呵呵~什么时打包上来研究研究~


[ 本帖最后由 soguu 于 2006-3-17 11:29 PM 编辑 ]