9

I got an array like this

$value = {array('id'=>$id, 'email'=>$email, 'token'=>$token)}

I want to stringify the array then encode then store it in cookie "login". How do you do that ? Also please tell me how to decode and read the stored value.

Edit:

I've been trying serialize/unserialize, but it didn't work as expected. for example,

$value = serialize(array('id'=>33, 'email'=>'big@gmail.com', 'token'=>'e9aa0966773d68e0fbf9cb21fc2877b4'));

echo $value; //a:3:{s:2:"id";i:33;s:5:"email";s:20:"big@gmail.com";s:5:"token";s:32:"e9aa0966773d68e0fbf9cb21fc2877b4";}

But when the value go to cookie, it looks like this

a%3A3%3A%7Bs%3A2%3A%22id%22%3Bs%3A1%3A%226%22%3Bs%3A5%3A%22email%22%3Bs%3A20%3A%22craigcosmo%40gmail.com%22%3Bs%3A5%3A%22token%22%3Bs%3A32%3A%22e9aa0966773d68e0fbf9cb21fc2877b4%22%3B%7D
angry kiwi
  • 10,730
  • 26
  • 115
  • 161
  • 1
    The cookie is never going to be plain text. The reason being is how it's stored in the HTTP header. The `Cookie:` header uses characters like colons and semicolons for delimiters, thus they need to be escaped out (PHP basically takes the cookie's value and performs a [url_encode](http://php.net/manual/en/function.urlencode.php) on it before outputting it to the client) – Brad Christie Jan 12 '11 at 18:14
  • so to read the cookie value I have to url_decode first? – angry kiwi Jan 12 '11 at 18:22
  • within php url_decode should happen automatically when it is building the $_COOKIE superglobal. – Jonathan Kuhn Jan 12 '11 at 18:28

2 Answers2

13

json_encode/json_decode

$_COOKIE['login'] = json_encode($array);
$array = json_decode($_COOKIE['login']);

Can also use serialize/unserialize:

$_COOKIE['login'] = serialize($array);
$array = unserialize($_COOKIE['login']);

Perhaps.


UPDATE

With this code:

<html><body><pre><?php
  $array = Array(
    'id'  => 1234,
    'email' => 'example@example.com',
    'token' => base64_encode('abcDEF1234')
  );
  
  echo "Var Dump (initial):\r\n";
  var_dump($array);
  
  $serialized = serialize($array);
  echo "Serialized:\r\n".$serialized."\r\n";
  
  $unserialized = unserialize($serialized);
  echo "Unserialized:\r\n".$unserailized."\r\n";
  var_dump($unserialized);
?></pre></body></html>

You would generate the following:

Var Dump (initial):
array(3) {
  ["id"]=>
  int(1234)
  ["email"]=>
  string(19) "example@example.com"
  ["token"]=>
  string(16) "YWJjREVGMTIzNA=="
}
Serialized:
a:3:{s:2:"id";i:1234;s:5:"email";s:19:"example@example.com";s:5:"token";s:16:"YWJjREVGMTIzNA==";}
Unserialized:

array(3) {
  ["id"]=>
  int(1234)
  ["email"]=>
  string(19) "example@example.com"
  ["token"]=>
  string(16) "YWJjREVGMTIzNA=="
}

EDIT2

You're seeing the encoded value based on how the HTTP protocol transfers cookies. There are two headers in a cookie transfer: Set-Cookie & Cookie. One is server->client, other other is client->server, respectfully.

When PHP sets the cookie (using setcookie e.g.) PHP is really just short-handing the following:

setcookie('login',$serialized);

which, in PHP translates to:

header('Set-Cookie: login='.urlencode($serialized).'; '
      .'expires=Wed, 12-Jan-2011 13:15:00 GMT; '
      .'path=/; domain=.mydomain.com');

If you had characters like : or a SPACE, the browser wouldn't know where the cookie's properties began and ended.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • 4
    Ah... the rarely used Jason encoding. :-) – John Parker Jan 12 '11 at 17:57
  • Did you mean "Jason_encode"? or is it a typo for "json_encode"? – Nico Burns Jan 12 '11 at 17:58
  • $array would actually be a STD_OBJECT unless you specify you want an array with with the optional 2nd parameter. – Marc B Jan 12 '11 at 17:59
  • @middaparka: Was using cell-phone, oops. I was bored while I'm waiting on Outlook to do it's initialization on a deploy. ;p Also, thought I'd offer json_de/encode to be different. One of the wonderful things of SO, so many solutions. – Brad Christie Jan 12 '11 at 18:02
  • @MarcB: `$array` was just symbolic of the array the user is trying to store/retrieve. – Brad Christie Jan 12 '11 at 18:04
  • yeah i got that too, but not done yet, when I put the value into cookie, I check the browswer to see cookie value, it a completely different value from what I put it, it has %%% all over the place. – angry kiwi Jan 12 '11 at 18:20
  • @runrunforest: please see the bottom of my answer (recently updated). This explains why it appears this way. – Brad Christie Jan 12 '11 at 18:24
10

NEVER EVER USE serialize with User input! serialize calls __wakeup and is a big security vulnerability, because you can execute code on the server. (Now the rules before you break 'em)

there is a serialize/unserialize function to convert an array to a string and back.

Edit: When you store a string to cookie (setcookie), php needs to do a url encode on the string. This prevents any characters in the string saved to cookie interfering with any other headers. When the page is loaded next, php gets the cookie and automatically does a url decode on the cookie value to return it to it's previous value. As far as what is stored in the cookie, this shouldn't matter within php because php will do the url encode/decode automatically. Now if you are getting the cookie in another language such as javascript, then yes, you will get the raw string back. In this case you can use something like decodeURI in JS to get the original value back.

Fabian Blechschmidt
  • 4,113
  • 22
  • 39
Jonathan Kuhn
  • 15,279
  • 3
  • 32
  • 43
  • 1
    did you try to base64_encode the string? Shouldn't be required, but if you are having trouble, it probably wouldn't hurt and might help prevent issues with characters that are not being properly encoded automatically. – Jonathan Kuhn Jan 12 '11 at 18:05
  • 3
    -1 serialize will call constructor of a serialized class. This is bad because it can cause code execution. Don't use on untrusted data. – goat Jan 12 '11 at 18:21
  • 1
    @rambocoder Is `json_encode`/`json_decode` safer then? That's what I've been using on user input. – Fabrício Matté Sep 05 '12 at 00:29
  • 3
    @FabrícioMatté Yes, json_encode/decode is safer. with serialize/unserialize it is possible to execute code (unserialize calls a __wakeup magic method if it exists on a class). You should never execute any user submitted code as you can never really verify 100% that it is not malicious. json_encode/json_decode doesn't call such methods so it is safer when dealing with user submitted data. The differences being that json is smaller in length, but you lose some data types. unserialize will return an instance of the specific class though, methods and all. – Jonathan Kuhn Sep 05 '12 at 17:42