Why does PHP replace pluses with spaces in $_COOKIE?

≡放荡痞女 提交于 2019-12-20 10:27:15

问题


So from my understanding of PHP and cookies, if I use the setcookie() function, then I get a cookie that is automatically url encoded. And when I go to the $_COOKIE array, I should get the cookie back, automatically url decoded. Problem is, it seems to be decoding the cookie twice when I look in $_COOKIE.

Say I have a cookie whose value is "Name|ID|Email", for example:

Joe|123|my+email@somewhere.com

This would be encoded as:

Joe%7C123%7Cmy%2Bemail%40somewhere.com

Notice the plus sign is encoded, so theoretically I ought to get it back if I decode it. Since this is automatically done in $_COOKIE, I ought to get back what I started with. But instead, I'm getting back:

Joe|123|my email@somewhere.com

Notice the space where the plus used to be. This is what I would expect if I ran an additional urldecode() on the cookie. But I'm not, so I have no idea why I would be getting a space instead of a plus.

Another interesting twist. A refresh on the page seems to produce the correct output. Any ideas why it's behaving like this?

FYI, to set the initial cookie, I use javascript and escape() the script to produce the encoded string. Might this be an hand off issue between javascript and PHP?

Thoughts would be appreciated.


回答1:


It's worth noting that both "%20" and "+" are valid encodings of a space character. Per the Wikipedia article on URL encoding (emphasis added):

When data that has been entered into HTML forms is submitted, the form field names and values are encoded and sent to the server in an HTTP request message using method GET or POST, or, historically, via email. The encoding used by default is based on a very early version of the general URI percent-encoding rules, with a number of modifications such as newline normalization and replacing spaces with "+" instead of "%20". The MIME type of data encoded this way is application/x-www-form-urlencoded, and it is currently defined (still in a very outdated manner) in the HTML and XForms specifications.

More specifically related to PHP and JavaScript, see the top answer on this question:

When to encode space to plus (+) or %20?




回答2:


if you don't want to auto encode your cookie you can use setrawcookie() function same as setcookie()
but with this function you can not use these chars inside value: (,; \t\r\n\013\014) :

setrawcookie("NAME","Joe|123|my+email@somewhere.com");  

output in resource - cookies in chrome :

Joe|123|my+email@somewhere.com 

when you echo $_COOKIE['NAME']

Joe|123|my email@somewhere.com

But : what i test it in php 5.3.13

setcookie("NAME","Joe|123|my+email@somewhere.com");

output in resource - cookies in chrome :

Joe%7C123%7Cmy%2Bemail%40somewhere.com  

when i echo $_COOKIE['NAME'] :

Joe|123|my+email@somewhere.com  

now : if you are still problem with this , you can use setcookie() function and then use rawurldecode() to decode it :

 echo rawurldecode($_COOKIE['NAME'])



回答3:


Firstly, PHP will always run before JavaScript - it's server side rather than client side so the cookie you set with JavaScript won't actually be available to PHP until you refresh the page (hence that issue).

Next JavaScript has different ways to encode the strings; only one will work with PHP automatically.

So:

document.cookie = "testuser=" + "Joe|123|my+email@somewhere.com";
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + escape("Joe|123|my+email@somewhere.com");
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + encodeURI("Joe|123|my+email@somewhere.com");
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com");
// Joe|123|my+email@somewhere.com 

So, try this for the sake of a test (remember you'll need to refresh the page to see the cookie value):

<html>
<head>
    <title>Cookie Juggling</title>
    <script type="text/javascript">
        document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com");
    </script>
</head>

<body>
    <div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>


来源:https://stackoverflow.com/questions/14383715/why-does-php-replace-pluses-with-spaces-in-cookie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!