这是来自较大应用程序的示例脚本,但显示了我尝试执行的操作的一般过程。如果我有以下脚本:
<?php
ob_start();
setcookie('test1', 'first');
setcookie('test1', 'second');
setcookie('test1', 'third');
setcookie('test2', 'keep');
//TODO remove duplicate test1 from headers
ob_end_clean();
die('end test');
我收到以下回复(通过Fiddler查看):
HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
end test
问题是Set-Cookie: test1
...存在3个不同的时间,因此不必要地增加了标题大小。 (再次,这是一个简化的例子 -
实际上,我在~800字节范围内处理~10个重复的cookie。)
有什么我可以代替完全摆脱标题的TODO
或者它只显示一次吗?,即以下是我的最终目标:< / p>
HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
end test
虽然Set-Cookie: test1=third
也不存在,但这很好,但Set-Cookie: test2=keep
需要保留。当我尝试setcookie('test1', '', 1);
删除Cookie时,会添加一个额外的标头以将其标记为已过期:
Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Set-Cookie: test1=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
如果我尝试删除标题,如:
if (!headers_sent()) {
foreach (headers_list() as $header) {
if (stripos($header, 'Set-Cookie: test1') !== false) {
header_remove('Set-Cookie');
}
}
}
当我只想删除Set-Cookie
时,它会删除所有test1
标题。
答案 0 :(得分:2)
正如您在最后一段代码中所建议的那样,headers_list()函数可用于检查已发送的标头。使用它,每个cookie的最后一个值可以存储在一个关联数组中。可以使用explode()(以及trim())提取名称和值。
当检测到多个具有相同名称的Cookie时,我们可以像您一样使用header_remove()调用,但随后将Cookie设置为最终值。请参阅下面的示例,以及this example phpfiddle。
if (!headers_sent()) {
$cookiesSet = array(); //associative array to store the last value for each cookie
$rectifyCookies = false; //multiple values detected for same cookie name
foreach (headers_list() as $header) {
if (stripos($header, 'Set-Cookie:') !== false) {
list($setCookie, $cookieValue) = explode(':', $header);
list($cookieName, $cookieValue) = explode('=', trim($cookieValue));
if (array_key_exists($cookieName, $cookiesSet)) {
$rectifyCookies = true;
}
$cookiesSet[$cookieName] = $cookieValue;
}
}
if ($rectifyCookies) {
header_remove('Set-Cookie');
foreach($cookiesSet as $cookieName => $cookieValue) {
//might need to consider optional 3rd - 8th parameters
setcookie($cookieName, $cookieValue);
}
}
}
缓存控制 max-age = 0,无缓存,无存储,必须重新验证
连接保持活力
内容编码 gzip
内容类型 text / html;字符集= UTF-8
日期 2017年4月26日星期三15:31:33 GMT
Expires Wed,11 Jan 1984 05:00:00 GMT
Pragma no-cache
服务器 nginx
Set-Cookie test1 =第三个 测试2 =保持
转移编码分块
变化接受编码
答案 1 :(得分:0)
我不明白为什么你认为你向我们展示的cookie删除代码会删除test2的setcookie。
如果您的代码多次设置相同的Cookie,则需要更改代码,以便多次停止设置Cookie!其他任何事情都是一个草率的解决方法。