PHP-php读写cookie时的编码问题
由于Cookie有特殊字符的限制,所以php在操作cookie时,最好加上编码,将特殊字符过滤掉,同时考虑到最好能缩短字符串长度,还可以加入gzcompress,最后我是这样做的:
$cookie = base64_encode(gzcompress(serialize($value)));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Cookie还是URL还是Post Data一般都是直接用urlencode来处理的。适应国际化标准,用UTF-8进行编码,长度也不会太长;最大的好处当然还是,对英文字母之类的内容,直接就能看得到。至于gzip,一般cookies不会太长(比HTML正文短多了),而且加了base64之后可能没压缩反而变长了,不一定有好处。
另一个巨大的好处是PHP下面可以直接用http_build_query来构造一个对象对应的字符串(当然,前提是里面只用到了字符串或者字符串数组,而没有handle之类的奇怪东西;整数可以自动转换问题也不大)。这个字符串虽然有一大堆百分号,但基本是可读的
$cookie = http_build_query($value);
读取的时候:
parse_str($cookie, $value);
很简单对吧。
另外的另外,setcookie这个函数会自己处理urlencode,所以没必要自己再编一次,只要:
setcookie('Value',http_build_query($value));
parse_str($_COOKIE['Value'], $value);
就行了。
javascript下面可以自己写类似的函数来处理这个值,不过如果真的想要在javascript下面用这个值的话可以考虑另一个方法:把http_build_query换成json_encode,编码成json方式,这样在javascript里面处理时可谓轻松愉快。
setcookie('Value',json_encode($value));
$value = json_decode($_COOKIE['Value'], true);
如果cookies被设成了无效的内容,这里会安全地返回null。
这种情况下一次base64是不保险的,比如url,你一次加密有些特殊字符还是被转义了。我一般至少两次base64_encode。
至于cookie安全读写的方法,我说一下我一般的方法。
无论是在客户端创建cookie,服务端读取;还是服务端创建,客户端读取。首先最好要保证这两者使用的函数保持一致,这样才能不容易出错。举个例子:
比如,在客户端创建或读取cookie的时候我一般用escape()和unescape()来避免cookie值中的特殊字符被转义,而在php端(我原来以为)urlencode和urldecode与上面js的函数对应,其实是不对的,如果在php端用这两个函数来创建或读取客户端的cookie,出现乱码的可能性非常大。正确的做法是,你得再php端来模拟js的escape()和unescape()这两个函数功能,下面是我一般用的函数:
//UTF-8 js escape实现
function escape($str) {
preg_match_all("/[xc2-xdf][x80-xbf]+|[xe0-xef][x80-xbf]{2}|[xf0-xff][x80-xbf]{3}|[x01-x7f]+/e",$str,$r);
$str = $r[0];
$l = count($str);
for($i=0; $i <$l; $i++) {
$value = ord($str[$i][0]);
if($value < 223) {
$str[$i] = rawurlencode(utf8_decode($str[$i]));
}
else {
$str[$i] = "%u".strtoupper(bin2hex(iconv("UTF-8","UCS-2",$str[$i])));
}
}
return join("",$str);
}
//UTF-8 js unescape实现
function js_unescape($str) {
$ret = '';
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
if ($str[$i] == '%' && $str[$i+1] == 'u') {
$val = hexdec(substr($str, $i+2, 4));
if ($val < 0x7f) $ret .= chr($val);
else if($val < 0x800) $ret .= chr(0xc0|($val>>6)).chr(0x80|($val&0x3f));
else $ret .= chr(0xe0|($val>>12)).chr(0x80|(($val>>6)&0x3f)).chr(0x80|($val&0x3f));
$i += 5;
}
else if ($str[$i] == '%') {
$ret .= urldecode(substr($str, $i, 3));
$i += 2;
}
else $ret .= $str[$i];
}
return $ret;
}
以上纯属个人见解,仅供参考!