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
CODE:[Copy to clipboard]<?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;
}
.............
?>
通过以上代码所示,我们通过分析流程,很轻松的就把数据重组后存储到cookie中。至于如何取得cookie,那是下篇文章的内容了。近期我会剖析整个
www.gbrss.com 网站架构过程。把心得体会写出来与大家共享讨论。
文字文字文字