使用header("Set-cookie")设置cookie与使用setcookie()函数的区别

14

我正在重构一些代码,找到了一些我从未见过的东西。这个函数用于用户登录时设置Cookie:

  function setUserCookie($name, $value) {
     $date = date("D, d M Y H:i:s",strtotime('1 January 2015')) . 'GMT';
     header("Set-Cookie: {$name}={$value}; EXPIRES{$date};");
  }

现在我被分配重构代码,计划使用setcookie函数,根据php.net的说法,它本质上执行相同的操作。

我的问题是:这两者之间是否有任何区别,我应该使用哪一个?

注意:此代码是很久以前编写的,因此我假设那时候setcookie不存在?


你可能会发现new Cookie($name)很有用,它在这个独立的库中可以找到。所以这是设置cookie的第三种选择。老实说,永远不要直接设置HTTP头。使用内置的PHP函数或此处引用的构造函数来设置cookie,以使用自动构建的标头值正确转义值。 - caw
5个回答

8

没有不使用setcookie的好理由。上面的代码没有正确编码名称和值,因此重构至少有一个主要优点。


setcookie()在32位系统上无法传递2038。这对于嵌入式平台上的Web服务器是一个问题(它们将不会得到更新)。 - Simon
setcookie()没有Psr-7的等效函数,除非使用兼容性包。 - mopsyd

5
这两个函数的区别在于,header() 是设置 HTTP 头信息的通用函数,而 setcookie() 则是专门用于设置 Set-Cookie 头信息的。

因此,header() 接收一个包含完整头信息的字符串作为参数,而 setcookie() 则需要提供多个与 cookie 相关的参数,并从这些参数中创建 Set-Cookie 头信息。

5

下面是一个无法使用setcookie的用例:

  • 你在PHP<7.3上运行网站
  • 你必须设置'SameSite' cookie属性

你可以通过利用setcookie中的一个bug来实现,但是我不会依赖于bug,因为bug会随时间修复:setcookie('samesite-test', '1', 0, '/; samesite=strict');

或者您可以使用PHP的header函数:header("Set-Cookie: samesite-test=1; expires=0; path=/; samesite=Strict");

请注意,在设置samesite属性时需要secure选项


干得好。这正是我为我的PHP 5.5+服务器所寻找的。感谢您的回复。 - Bokili Production

2

一个很大的区别是,setcookie总是将host_only设置为false,你无法改变它。

因此,如果由于某些原因您必须将host_only设置为true,则必须使用header方法。据我所知。

最初的回答:

一个重要的区别是setcookie总是将host_only设置为false,无法更改。因此,如果有必要将host_only设置为true,则必须使用header方法。就我所知。


1
我复制了我认为与setCookie完全相同的程序行为。这是我的实现,如果对其他人有用的话。
function setUserCookie($name, $value, $expires = 0, $path = "", $domain = "", $secure = false, $http_only = false) {
   $value = rawurlencode($value);
   date_default_timezone_set('UTC');
   $date = date("D, d-M-Y H:i:s",$expires) . ' GMT';
   $header = "Set-Cookie: {$name}={$value}";
   if($expires != 0) {
     $header .= "; expires={$date}; Max-Age=".($expires - time());
   }
   if($path != "") {
     $header .= "; path=".$path;
   }
   if($domain != "") {
     $header .= "; domain=".$domain;
   }
   if($secure) {
     $header .= "; secure";
   }
   if($http_only) {
     $header .= "; HttpOnly";
   }
   header($header, false);
}

与您的函数不同之处正是与setCookie(更多参数,如自定义过期时间、路径、域、安全和httpOnly)的不同之处。特别需要注意的是"header"的第二个参数(false),这样就可以通过对该函数进行不同调用来放置多个具有不同值的cookie。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接