PHP-php读写cookie时的编码问题

PHP-php读写cookie时的编码问题

偏爱自由 发布于 2017-02-05 字数 270 浏览 1036 回复 2

由于Cookie有特殊字符的限制,所以php在操作cookie时,最好加上编码,将特殊字符过滤掉,同时考虑到最好能缩短字符串长度,还可以加入gzcompress,最后我是这样做的:

$cookie = base64_encode(gzcompress(serialize($value)));

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜无邪 2017-10-07 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。

泛泛之交 2017-07-17 1 楼

这种情况下一次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;
}

以上纯属个人见解,仅供参考!