如何在纯PHP中解析$ _SERVER [' HTTP_COOKIE']?

时间:2015-06-08 16:37:26

标签: php cookies

我需要在纯PHP中解析$ _SERVER [' HTTP_COOKIE']字符串。我无法访问$ _COOKIE或http_parse_cookie(PECL)等函数。

我尝试使用类似的功能:

function ParseCookies($strHeaders)
{
$result = array();              
    $aPairs = explode(';', $strHeaders);
    foreach ($aPairs as $pair)
    {
        $aKeyValues = explode('=', trim($pair), 2);
        if (count($aKeyValues) == 2)
        {
            switch ($aKeyValues[0])
            {
                case 'path':
                case 'domain':
                    $aTmp[trim($aKeyValues[0])] = urldecode(trim($aKeyValues[1]));
                    break;
                case 'expires':
                    $aTmp[trim($aKeyValues[0])] = strtotime(urldecode(trim($aKeyValues[1])));
                    break;
                default:
                    $aTmp['name'] = trim($aKeyValues[0]);
                    $aTmp['value'] = trim($aKeyValues[1]);
                    break;
            }
        }
        $result[] = $aTmp;
    }
return $result;
}

但是爆炸模式很简单,因为我可以拥有像name="a;b;c=1;";

这样的cookie

我需要以正确的方式对字符串进行标记。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

例如,解析Cookie:的原始值

datr=xxx; expires=Wed, 10-Feb-2021 03:05:45 GMT; Max-Age=63071999; path=/; domain=.facebook.com; secure; httponly

在PHP中非常简单,请使用parse_str

$raw_cookie = 'datr=xxx; expires=Wed, 10-Feb-2021 03:05:45 GMT; Max-Age=63071999; path=/; domain=.facebook.com; secure; httponly';

parse_str(strtr($raw_cookie, array('&' => '%26', '+' => '%2B', ';' => '&')), $cookies);

print_r($cookies);

Array
(
    [datr] => xxx
    [expires] => Wed, 10-Feb-2021 03:05:45 GMT
    [Max-Age] => 63071999
    [path] => /
    [domain] => .facebook.com
    [secure] => 
    [httponly] => 
)

您可能会注意到,但我们甚至不必担心;后面的空间。同样parse_str也会进行urldecode。

请注意,cookie名称中的点(。)和空格()被下划线(_)替换。就像$_COOKIE。即使RFC 6265允许点(。)。

配对功能将是:

echo http_build_query($cookies, '', '; ', PHP_QUERY_RFC3986);

除了空格将被编码为%20之外,它将转换回原始cookie字符串。

答案 1 :(得分:0)

一些改进,但不是令牌!

Class CookieParser{
    public $cookies = array();
    function __construct($str){
        foreach(explode('; ',$str) as $k => $v){
            preg_match('/^(.*?)=(.*?)$/i',trim($v),$matches);
            $this->cookies[trim($matches[1])] = urldecode($matches[2]);
        }
    }
}

$CP = new CookieParser($_SERVER['HTTP_COOKIE']);
print_r($CP->cookies);

答案 2 :(得分:0)

真的很喜欢@Andrej的答案...但是我想要一个函数(而不是一个类),并且还可以保留多个同名的Cookie ...这些答案目前都无法执行,因为您无法拥有关联具有多个同名键的数组。

function CookieParser($str){
    $cookies = array();
    foreach(explode('; ',$str) as $k => $v){
        preg_match('/^(.*?)=(.*?)$/i',trim($v),$matches);
        array_push($cookies, array(trim($matches[1]), urldecode($matches[2])));
    }
   return $cookies;
}

$CP =  CookieParser($_SERVER['HTTP_COOKIE']);

Produces:

Array
(
[0] => Array
    (
        [0] => username
        [1] => admin
    )

[1] => Array
    (
        [0] => page
        [1] => 5
    )

[2] => Array
    (
        [0] => page
        [1] => 9
    )

)

尽管要小心处理多个具有相同名称的cookie,但不要偶然验证值1,而是使用值2。