SESSION 与 COOKIE
一. 各自的特点
1. COOKIE 在浏览器端和服务器端都能获取到;SESSION只能在服务器端访问。
二. 实践
1. JAVASCRIPT 子COOKIE
《javascript高级程序设计》提到了“子COOKIE”的概念,大致的意思是为了在一条COOKIE中尽可能多保存信息。使用以下形式设置COOKIE:
name=name1=value1&name2=value2&name3=value3
在JAVASCRIPT中设置子COOKIE的技巧是,对该字符串中的name和value进行URL编码,而对等号(=)和与号(&)不编码。获取子cookie的技巧是,先用&后用=进行字符串分割,然后再解码。这样即使name1等或者value1等中包含等号(=)或与号(&)都能不失真地设置和获取子COOKIE。
2. PHP 子COOKIE
笔者在实践过程中,也曾想用PHP实现这种不失真的子COOKIE。不过在有限的时间内没有找到好的办法,由于使用PHP的setcookie函数设置COOKIE值会自动进行URL编码,所以这明显不符合我的需求。于是采用setrawcookie() 函数。并且,默认name1/value1之类的不包含等号(=)和与号(&)。
我用PHP封装的子COOKIE如下,在我最近做的小网站中派上用场了,挺方便。
class CookieUtil
{
//name value expire path domain secure httponly
//把名值对都存入数组中,作为参数传入
public static function setSubCookie($sName,$aPairs,$iExpire=0,$sPath='/',$sDomain="",$bSecure=false,$bHttpOnly=false)
{
$sCookieText = "";
$bFirst = true;
if($aPairs)
{
//遍历数组进行编码,等号和&符号不编码
foreach($aPairs as $key=>$value)
{
// echo $key.$value;
if(strlen($key) > 0)
{
if(!$bFirst)
{
$sCookieText .= "&";
}
$sCookieText .= urlencode($key)."=".urlencode($value);
$bFirst = false;
}
}
// echo $sCookieText;
}
return setrawcookie(urlencode($sName),$sCookieText,$iExpire,$sPath,$sDomain,$bSecure,$bHttpOnly);
}
public static function getSubCookie($sName)
{
$aPairs = array();
if(isset($_COOKIE[urlencode($sName)]))
{
$sCookieText = $_COOKIE[urlencode($sName)];
$aKeyVals = explode('&',$sCookieText);
foreach($aKeyVals as $value)
{
$aKeyAndVal = explode('=',$value);
// var_dump($aKeyAndVal);
$aPairs[$aKeyAndVal[0]] = $aKeyAndVal[1];
}
}
// var_dump($aPairs);
return $aPairs;
}
}
千言万语汇成一句话,不解释~
使用方法大致是:
<?php
//设置
$aInput['uname']="智译哥";
$aInput['umail']="xxxx@qq.com";
CookieUtil::setSubCookie('user',$aInput,time()+3600*24*30,"/",$yourSite,false,false);
?>
<?php
//获取
$aOutput = CookieUtil::getSubCookie('user');
echo $aOutput['uname'];
echo $aOutput['umail'];
?>
3. 意外
苦于差劲的网络状况,不得不使用XAMPP来本地建站调试,期间使用我心爱的CookieUtil::setSubCookie时,发现在FF和Chrome下无法设置COOKIE,其它如FF和OPERA没问题。在诸多调试之后,KB的我才意识到也许是LOCALHOST的问题,我调用setSubCookie时传入的域名参数是localhost,这不是一个有效的域名,IE和OPERA都不支持,放到线上就OK了。
这个折腾让时间已不多的我心痛不已。