Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PHP replace pluses with spaces in $_COOKIE?

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|[email protected]

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 protected]

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.

like image 704
user1630830 Avatar asked Jan 17 '13 16:01

user1630830


People also ask

What is the purpose of $_ cookie variable in PHP?

Definition and Usage The setcookie() function defines a cookie to be sent along with the rest of the HTTP headers. A cookie is often used to identify a user. A cookie is a small file that the server embeds on the user's computer. Each time the same computer requests a page with a browser, it will send the cookie too.

What is the use of $_ cookie?

PHP setcookie() function is used to set cookie with HTTP response. Once cookie is set, you can access it by $_COOKIE superglobal variable.

Can we destroy cookie in PHP?

No, Actually, there is not a way to directly delete a cookie. Just use a set cookie with an expiration date in the past, to trigger the removal mechanism in your browser.

Where does PHP store cookie?

Cookies are always stored in the client. The path only sets restrictions to what remote pages can access said cookies. For example, if you set a cookie with the path "/foo/" then only pages in the directory "/foo/" and subdirectories of "/foo/" can read the cookie.


2 Answers

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?

like image 192
DreadPirateShawn Avatar answered Sep 22 '22 15:09

DreadPirateShawn


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|[email protected]";
// Joe|123|my [email protected] (when decoded by PHP)

document.cookie = "testuser=" + escape("Joe|123|[email protected]");
// Joe|123|my [email protected] (when decoded by PHP)

document.cookie = "testuser=" + encodeURI("Joe|123|[email protected]");
// Joe|123|my [email protected] (when decoded by PHP)

document.cookie = "testuser=" + encodeURIComponent("Joe|123|[email protected]");
// Joe|123|[email protected] 

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|[email protected]");
    </script>
</head>

<body>
    <div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>
like image 44
CD001 Avatar answered Sep 24 '22 15:09

CD001