PHP 中内置函数 setcookie() 和 setrawcookie() 的实际实际差异是啥?

Posted

技术标签:

【中文标题】PHP 中内置函数 setcookie() 和 setrawcookie() 的实际实际差异是啥?【英文标题】:What is/are the actual practical difference/s in functioning of the built-in functions setcookie() and setrawcookie() in PHP?PHP 中内置函数 setcookie() 和 setrawcookie() 的实际实际差异是什么? 【发布时间】:2018-02-21 21:32:08 【问题描述】:

我正在详细学习 PHP 中的 Cookies 最重要的概念之一。

在学习Cookies的过程中,我了解到“cookie的值在发送cookie时会自动进行URLencoded,接收时会自动解码(为了防止URLencoding,请改用setrawcookie() )。"

上面的说法让我产生了很多疑问,如下:

    “发送 cookie 时自动对 cookie 的值进行 URL 编码,接收时自动解码”,实际发生了什么? 既然已经有一个函数 setcookie() 可用于设置 cookie 值,为什么还需要另一个函数,例如 setrawcookie()URL编码URL解码的过程是否不安全/有害/危险/慢/还有什么应该避免的吗? 使用setrawcookie() 比使用setcookie() 有哪些好处/缺点? 哪个是安全/更好/安全/可靠/等等。 setcookie()setrawcookie()? 不能像$_COOKIE['cookie_variable'] = 'some_value' 等其他变量一样设置cookie,而不是使用setcookie()setrawcookie()

如果有人能用完美、合适且易于理解的代码示例以及逐步清晰、清晰、易于理解的解释来清除我上面提到的所有疑问,那对我有很大帮助。

谢谢。

【问题讨论】:

在我看来这是一项艰巨的任务。怀疑任何人都会回答所有问题。 urlencode:php.net/manual/en/function.urlencode.php 【参考方案1】:
    通过“发送 cookie 时自动对 cookie 的值进行 URL 编码,接收时自动解码”,实际发生了什么?

这意味着您不必担心特殊字符。

请注意,cookie 不是 PHP 概念;它们是 HTTP 协议的扩展。而且每个协议都有一个您需要遵守的严格结构,否则它根本不起作用。该结构依赖于分隔符 - 字符或在该协议中分配给它们的具有特殊含义的字符序列。 通过每个协议传输的数据不可避免地会包含这些特殊字符,这就是编码的必要性。

例如,分号 (;) 在 Set-Cookie HTTP Header 中用作分隔符,因此如果您的 cookie 值包含它,则需要对其进行编码,否则浏览器将无法正确解析 cookie他们收到了。

如果您发送的 cookie 的值为 foo;bar,但未进行编码,浏览器会将其视为附加了 bar 的值 foo标志。 您将丢失;bar 作为数据的一部分,并且由于根据协议bar 是一个未知标志,浏览器将简单地忽略它,因此您甚至根本不知道有错误。

当你用setcookie()设置一个cookie时,PHP会自动进行编码,然后当你从$_COOKIE超全局读取时自动解码。

    既然已经有函数 setcookie() 可用于设置 cookie 值,为什么还需要另一个函数,如 setrawcookie()?

主要有两个原因:

    您发送的值可能已经被编码了。

    您希望避免双重编码,因为这充其量意味着您需要做更多的工作。在最坏的情况下,它可能会完全破坏数据(即您可能永远无法 100% 确定原始数据是什么)。

    编码值的方法有很多种,setcookie() 使用的那一种可能并不理想。

    URL 编码编码的数据通常比 cookie 格式需要的多。 在极端情况下(您永远不必担心这一点),由于编码数据的大小通常比原始数据大,它可能会导致它超过最大 cookie 大小(大约 4kb)。或者您可能只是想节省带宽。

但您 100% 知道数据不需要编码的情况也很常见,因此您只是想跳过那个不必要的步骤。

    URL 编码和 URL 解码的过程是否不安全/有害/危险/慢/还有什么应该避免的吗?

一般来说不是,但这应该已经在上面回答了。

    使用setrawcookie() 比使用setcookie() 有哪些好处/缺点?

缺点是如果需要,您需要自己对值进行编码。 上面已经再次解释了这些好处。

    哪个是安全/更好/安全/可靠/等等。 setcookie()setrawcookie()?

setcookie() 为不熟悉cookie protocol 的人留下的错误空间更少。

但这是有代价的——假设您总是需要 URL 编码。假设在编程中通常是一件坏事。

对于新手来说,setcookie() 更容易使用。 对于专家来说,setrawcookie() 限制较少,因此更加灵活。

两者本质上都不是更好,而且由于您提到“安全” - 两者都对安全性没有任何影响。

    不能像$_COOKIE['cookie_variable'] = 'some_value' 等其他变量一样设置cookie,而不是使用setcookie()setrawcookie()

没有。

【讨论】:

【参考方案2】:

URL 编码将在 URL/HTTP 中具有特殊含义的特定字符替换为百分比编码的字符,例如一个空格变成%20。有关血腥细节,请参阅https://en.wikipedia.org/wiki/Percent-encoding。

无论出于何种原因,如果您想设置一个您已经自己进行 URL 编码的 cookie,您需要 setrawcookie。因此,如果您有一个已编码的 cookie,其中包含值 %20,如果您使用 setcookie,它将被编码为 %2520;使用setrawcookie,它将按原样保留并设置为%20。换句话说,setrawcookie 是一种“设置该死的 cookie,我知道我在做什么。” 使用它来确保 cookie 格式正确符合 HTTP字符编码标准。

如果您首先需要有关什么编码或转义格式的更多背景信息,请参阅The Great Escapism (Or: What You Need To Know To Work With Text Within Text)。

【讨论】:

以上是关于PHP 中内置函数 setcookie() 和 setrawcookie() 的实际实际差异是啥?的主要内容,如果未能解决你的问题,请参考以下文章

PHP setcookie 网络函数

PHP基础cookies和session

php header setcookie headers_sent函数 函数检查 HTTP 标头是否已被发送以及在哪里被发送

PHP:setcookie() 和 unset() 不删除 cookie

php setcookie中path和domain怎么设置

php 跨二级域名 设置cookie