trante
trante

Reputation: 33996

CakePHP setting multiple values into one cookie

I know that multiple values can be set to cookie this way:

If you want to write more than one value to the cookie at a time,
    you can pass an array:

$this->Cookie->write('User',
    array('name' => 'Larry', 'role' => 'Lead')
);

Due to some design issues, I need to set cookie values in different parts of my controller action. But it seems like this minimalized code doesn't work:

public function myfunction() {
    $text = "";
    // to be sure that this cookie doesn't exist
    $this->Cookie->delete('mycookie');
    // getting data from cookie, result is NULL
    $data = $this->Cookie->read('mycookie');
    $text .= "data 1 type: ".gettype($data)."<br>";
    $key="mike";
    $value=12;
    // adding key-value to cookie
    $data[$key] = $value;
    // serializing and writing cookie
    $dataS = json_encode($data);
    $this->Cookie->write('mycookie', $dataS, FALSE, '10 days');

    // reading cookie again, but this time result is
    // string {"mike":12} not an array
    $data = $this->Cookie->read('mycookie');
    $text .= "data 2 type: ".gettype($data)."<br>";
    $key="john";
    $value=20;
    // Illegal string offset error for the line below
    $data[$key] = $value;
    $dataS = json_encode($data);
    $this->Cookie->write('mycookie', $dataS, FALSE, '10 days');

    echo $text;

}

Page output:

Warning (2): Illegal string offset 'john' [APP/Controller/MyController.php, line 2320]  
data 1 type: NULL   
data 2 type: string  

From the code above, "Mike 12" is set to cookie successfully. But when I read cookie data for the second time, I get a string like this: {"mike":12}. Not an array.

When I make gettype for "data 2" the output is "string".
So when I make $data["john"]=20 I get Illegal string offset error because $data is string not array.

So is it not possible to set same cookie in an action, one by one ?

Edit: When I create a data array, json_encode that array and write its contents to cookie. Then when in another controller, when I read that cookie contents and assign it so a variable, it is automatically converted to Array.

Upvotes: 1

Views: 1777

Answers (1)

ndm
ndm

Reputation: 60503

Encoding and decoding the data in JSON format is an internal functionality of the Coookie component on which your application should not rely! The implementation might change, and your code will break.

Currently decoding of JSON data happens only when the data was actually read from the cookie, which requires a new request. On the same request you would access the original data buffered by the component.

So instead of this JSON thingy you should follow the conventions and pass an array:

$data = array();

$key = 'mike';
$value = 12;

$data[$key] = $value;

$this->Cookie->write('mycookie', $data);

// ... do some stuff, and then somewhere else:

$data = $this->Cookie->read('mycookie');

$key = 'john';
$value = 20;

$data[$key] = $value;
$this->Cookie->write('mycookie', $data);

or use dot notation (this will result in multiple cookies):

$key = 'mike';
$value = 12;
$this->Cookie->write('mycookie.' . $key, $value);

// ... do some stuff, and then somewhere else:

$key = 'john';
$value = 20;
$this->Cookie->write('mycookie.' . $key, $value);

See also http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#using-the-component

Upvotes: 2

Related Questions