How to store a php array inside a cookie? - php

I'm trying to create a php to do list using cookies, however am struggling to store the cookie inside an array so that I can add more than one cookie.
When I submit the form, a cookie is added, but when I go to add another the first one is replaced.
I want to store the cookie in a variable, push it to an array then save it to the end of the list rather than replace the current cookie.
Here is the code I have so far:
if (isset($_POST['submit'])) {
$task = htmlentities($_POST['task']);
$tasks = array ();
if(isset($_COOKIE[$task])) {
array_push($tasks, $task);
echo $_COOKIE[$task];
} else {
}
setcookie('task', $task, time() + 3600);
header('Location: index.php');
}
I'm not sure on exactly where I'm going wrong, would anyone be able to help?

When you store a cookie with the same name, it gets overwritten. You also seem to be storing the individual task and not the array. If you would like to store the array safely, you can attempt to store it as JSON.
It would look like this:
if (isset($_POST['submit'])) {
$task = htmlentities($_POST['task']);
//Check if the cookie exists already and decode it if so, otherwise pass a new array
$tasks = !empty($_COOKIE['tasks']) ? json_decode($_COOKIE['tasks']) : [];
//if(isset($_COOKIE[$task])) {
array_push($tasks, $task);
// echo $_COOKIE[$task];
//}
$encodedTasks = json_encode($tasks);
setcookie('task', $encodedTasks, time() + 3600);
header('Location: index.php');
}
You seem to be checking if the value of the post variable is a key in your array rather than using the 'tasks' key as you set in your setcookie. You do not need to see if the array exists again as you passed either the decoded array or the empty array as 'task'

There are a few things wrong with your code. First of all, you cannot story an array in a cookie, only strings. Whay you can do is transform your cookie to JSON when setting it, and when you are getting it decode it. Also, when pushing to you array, the array you are pushing to is reset on every request. To get around this, first get you data from the cookie. Something like this is what I would use:
const COOKIE_NAME = 'tasks';
$tasks = ['one', 'two'];
setcookie(COOKIE_NAME, json_encode($tasks));
$newTask = 'another task';
if (isset($_COOKIE[COOKIE_NAME])) {
$tasks = json_decode($_COOKIE[COOKIE_NAME], true);
array_push($tasks, $newTask);
setcookie(COOKIE_NAME, json_encode($tasks));
}
var_dump(json_decode($_COOKIE[COOKIE_NAME], true)); // Every request after the first time a cookie is set "another task" is added to the cookie.

Related

Parent array keys taking precedence

My session array looks like the following:
$_SESSION => array(
"acc"=>array(
"name"=>"Account name",
"id"=>1,
...
),
"name"=>"User name",
...
);
To clarify, please note that this is just to show the format. I am not actually setting $_SESSION to a new array. For that code, please see the end of the question.
If I dump the $_SESSION, I get just what I expect; however, if I try to reference one of the "acc" variables that has the a key that is used in the parent session array, it will give me the result stored in the session array.
For instance
$_SESSION["acc"]["name"]
This returns "User name", when it should return "Account name".
Why is this?
If I set the acc variable key to something else, like aname, e.g.
$_SESSION["acc"]["aname"]
This returns "Account name" like it should.
Session creation code:
session_start();
$acc = array(
"id"=>$accid,
"sub"=>$sub,
"name"=>$name,
"exp"=>$exp
);
$_SESSION["acc"] = $acc;
$_SESSION["admin"] = $admin;
$_SESSION["name"] = "$fname $lname";
$_SESSION["uid"] = $uid;
This appears to be a bug. After messing around with key names, I found that after changing the key names and undoing my changes to make the key names the same again, it worked, but after doing it again, it didn't.
Because $_SESSION is already an array when you write $_SESSION = array (.... You created array of array.

How to set an array in session in codeigniter?

I am little bit struggling in setting array in session.
Here is my code:-
Controller:
function taketest(){
$this->load->model('', '');
$questions_for_test = $this->session->userdata('questions_for_test');
$difficulty_level = $this->session->userdata('difficulty_level');
$question_id = $this->session->userdata('question_id');
if($question_id==""){
$question_id = $this->myjcat->returnRandomQuestion($questions_for_test,$difficulty_level);
$this->session->set_userdata('question_id',$question_id);
}
$question_details = $this->myjcat->getQuestion($question_id);
}
Model:
function returnRandomQuestion($questions_for_test, $difficulty_level){
$question_id = array_rand($questions_for_test[$difficulty_level], 1);
$used_question=array();
$used_questions=$questions_for_test[$difficulty_level][$question_id];
$this->session->set_userdata('used_questions',$used_questions);
return $questions_for_test[$difficulty_level][$question_id];
}
But when I call:
$used_questions = $this->session->userdata('used_questions');
in controller
in the controller it will not return me an array.It gives me last value stored in it.
I could be misreading things, but it looks like you are only storing one value.
// this code:
$used_questions=$questions_for_test[$difficulty_level][$question_id];
$this->session->set_userdata('used_questions',$used_questions);
// is the same as this code
$this->session->set_userdata('used_questions',$questions_for_test[$difficulty_level][$question_id]);
You're probably looking for this:
// fetch the stored copy first.
$used_questions = $this->session->userdata('used_questions');
if(!is_array($used_questions)) $used_questions = array();
// note the []
$used_questions[] = $questions_for_test[$difficulty_level][$question_id];
$this->session->set_userdata('used_questions',$used_questions);
You can set array values in session data like this :-
$this->session->set_userdata('used_questions', json_encode($used_questions));
And retrieve the data as :-
json_decode($this->session->userdata('used_questions'));
If you want the retrieved array data as associative array :-
json_decode($this->session->userdata('used_questions'), true);
Hope it hepls you :)
The problem is that $used_questions is storing the value stored in $questions_for_test[$difficulty_level][$question_id] and not the array.
So do this $this->session->set_userdata('used_questions',$questions_for_test);
This is because the data you pass to the $used_questions is a value.
You might want to do something like this:
array_push($used_questions, $questions_for_test[$difficulty_level][$question_id]);
*appending / adding a new value to an array

Iterate over KEYLESS JSON array?

I'm building a shopping cart and using a cookie to store the cart contents in a JSON object.
On each page, using Javascript, I need to retrieve the cookie, parse the JSON and iterate over each row, to display the described product in the basket summary.
I decided not to use keys in the array, since if I have a record of the designation of each position, why do I need to store it in the cookie. I thought that was a smart idea, but now all my searching turns up are suggestions to use the keys.
This is a sample of the JSON:
{
"9999.9999":["CentOS6",2,"0.5",150,"23.90"],
"0002.0004":["Support5","","3",5,"12.99"],
"9999.9999":["UbuntuServer12.04LTS",1,"1",220,"42.60"]
}
I was expecting to be able to access the 'price' for example (which is in the last field of each row) of the 2nd record, like so:
basket = JSON.parse(basket);
price = basket[1][4];
That doesn't seem to work.
There are really two parts to this question.
How to cherry pick a value directly from the basket?
How to iterate through it, allowing me to operate on each row in turn?
In case you're wondering about the first field. That is the SKU of the product. The reason there are two "9999.9999" is because that is a reserved number, indicating that the product was a 'custom' product (doesn't refer directly to a catalogue item).
UPDATE
Based on #Samer's answer below, I have updated the code to use arrays, as follows:
The JSON now looks like this:
[
["9999.9999","CentOS6",2,"0.5",150,"23.90"],
["0002.0004","Support5","","3",5,"12.99"],
["9999.9999","UbuntuServer12.04LTS",1,"1",220,"42.60"]
]
I'm now attempting to access it from the cookie as follows:
var basket = readCookie('basket');
basket = JSON.parse(basket);
alert( 'Price of item 2 =' + basket[1][5] );
Only, instead of alerting, 'Price of item 2 = 12.99' I get 'Price of item 2 = undefined'.
I'm wondering what I've done wrong?
UPDATE 2
Still having trouble with this. Maybe I should explain how we're getting the data into the cookie.
The array on the cookie can be updated on the server using PHP (when adding custom items) or client-side using Javascript when a catalogue item is added.
Currently, I'm concentrating on items added server side. I'm using the following code to add the cookie:
<?
extract($_POST, EXTR_SKIP);
// Get contents of existing basket (if any) minus last ']'
// so that it's ready to be added to.
if (isset($_COOKIE['basket'])) {
$basket = json_decode($_COOKIE['basket']);
$chars = strlen($basket)-1;
//echo "<pre>".var_dump($basket)."</pre>";
$cookieVal = substr($basket, 0, $chars);
$cookieVal .= ",
[\"9999.9999\",\"$sltOS\",$vcpuPoints,\"".$ramPoints."\",$storagePoints,\"".$baseServerCostMonthUSD."\"]]";
$cookieVal = json_encode($cookieVal);
/*
* Sample format
*
[["9999.9999","CentOS6",2,"0.5",150,"23.90"],
["0002.0004","Support5","","3",5,"12.99"],
["9999.9999","UbuntuServer12.04LTS",1,"1",220,"42.60"]]
*
*/
} else {
$cookieVal = json_encode("[[\"9999.9999\",\"$sltOS\",$vcpuPoints,\"".$ramPoints."\",$storagePoints,\"".$baseServerCostMonthUSD."\"]]");
}
$exp = time()+3600; // sets expiry to 1 hour;
setcookie ( 'basket' , $cookieVal, $exp, '/' );
Then client-side for reading the cookie, I have this, which is called when the page is loaded:
function initBasket() {
var basket = readCookie('basket');
if (isJSON(basket)) {
// We'll populate the basket
basket = JSON.parse(basket);
alert(basket[1][5]);
} else {
$('#sList').html('Your basket is empty.');
return;
}
}
UPDATE 3
Finally got it working. Thanks for your help.
Maybe the code can help others, so I've included the final code below:
The PHP:
if (isset($_COOKIE['basket'])) {
$cookieVal = json_decode($_COOKIE['basket']);
$cookieVal[] = array
(
"9999.9999",
$sltOS,
$vcpuPoints,
$ramPoints,
$storagePoints,
$baseServerCostMonthUSD
);
$cookieVal = json_encode($cookieVal);
} else {
$cookieArr[] = array
(
"9999.9999",
$sltOS,
$vcpuPoints,
$ramPoints,
$storagePoints,
$baseServerCostMonthUSD
);
$cookieVal = json_encode($cookieArr);
}
// Save VPS choice in basket cookie
$exp = time()+3600; // sets expiry to 1 hour;
setcookie ( 'basket' , $cookieVal, $exp, '/' );
The Javascript:
function initBasket() {
var basket = readCookie('basket');
if (isJSON(basket)) {
// We'll populate the basket
basket = JSON.parse(basket);
alert(basket[1][5]);
} else {
$('#sList').html('Your basket is empty.');
return;
}
}
If the JSON has no keys then it's an array, simply build your data using an array instead of key/value pairs.
var data = [
['CentOS', ''],
['Another Product', ...],
];
UPDATE:
So now based on your new answer, it looks like you're trying to JSON.parse the actual array. JSON.parse usually takes in a string value which has the array and then parses it into an actual array.
To see what I mean take your data array and run it through JSON.stringify and you will see the output, that same output you can then run it through JSON.parse
The problem is in PHP: You json_encode your array twice.
Here you manually encoded it once:
$cookieVal .= ",
[\"9999.9999\",\"$sltOS\",$vcpuPoints,\"".$ramPoints."\",$storagePoints,\"".$baseServerCostMonthUSD."\"]]";
Then here, you do it again:
$cookieVal = json_encode($cookieVal);
So as a result you get a string when you parse json it in javascript.
Obviously, second basket[1][4] gives you an undefined value, since basket is a string and basket[1] is a character.
It helps to use firebug or other debugging utility to take a look what data you get at every step.
So. Simply build an array of arrays in PHP and then json_encode it (once) and your js should work.
{
"9999.9999":["CentOS6",2,"0.5",150,"23.90"],
"0002.0004":["Support5","","3",5,"12.99"],
"9999.9999":["UbuntuServer12.04LTS",1,"1",220,"42.60"]
}
Mind the curly-brackets. This indicates that this is an object.
You cannot iterate through an object by numeric index.
Also mind the duplicated key "9999.9999", the first row will be overwritten by the third row.
You may try to use a for-in loop for looping through an object but this is not recommended.
var basket = JSON.parse(basket);
for(var key in basket)
{
var price = basket[key][4];
// do something with the price.
}
Anyways, this JSON object has structural problem. You should consider a better structure, an plain-old array should be good enough.

php multiple session name or sub-session name?

my script currect have two session called
$_SESSION['mypic']
and
$_SESSION['mypicsrc']
can I combine this two to one session and sub-session?
like this:
$_SESSION['mypic']
$_SESSION['mypic']['src']
the $_SESSION global is an array that will only store strings. If you want to store an array inside a $_SESSION var you have to serialize it first
$data = array( 'src' => '' );
$_SESSION['mypic'] = serialize($data);
then to get it back out you have to deserialize
$data = deserialize($_SESSION['mypic']);
However, you should store your data in a database and then store an id or reference to that particular record in $_SESSION.
Actually, you only have one session there, with the values stored in $_SESSION.
You can change them like any other variable;
$_SESSION['mypic']['src'] = $_SESSION['mypicsrc'];

storing multiple values of a variable in cookie and comparing

How can i store multiple values for a variable in cookie using php, for example
$id = 1,2,4,5
Then how can i compare the stored values with a variable? for example, $new_id=4, i want to check if $new_id value exists in the stored values of $id in cookie.
Thanks for help and have a nice day.
You can store arbitrary strings in cookie elements, so a serialized array should work. Example:
// To store:
$ids = array(1, 2, 3, 4);
setcookie('ids', serialize($ids));
// To retrieve:
$serialized = $_COOKIE['ids'];
$ids = unserialize($serialized);
// sanity check: $ids needs to be an array.
assert(is_array($ids));
// Now let's check:
if (in_array(4, $ids)) {
// Yes, it's here.
}
A few caveats though:
The cookie is completely in the hands of the client, and cookie values should never be trusted. Treat them just like you would treat query string parameters or POST data.
Cookies offer very limited storage (IIRC, the standard gives you 4096 bytes to work with).
With these in mind, it might be a better idea to store the array in $_SESSION instead - this will give you virtually unlimited storage, and the only way for the client application to fiddle with the values is through your code.
Try with following snippet.
// do Stuff to retrieve value of $id from cookie.
// explode variable to array
$idArr = explode(',' , $id);
// check existence of new_id in cookie variable.
if(in_array($new_id , $idArr)){
// new_id exist in cookie variable
}
Hope this will help
Thanks!
Hussain.
to use the multiple value you can use the array and then to store it you can serialize ( and unserialize) the array.
To create array: $array = array(1,2,3,4);
To compare: if (in_array(2,$array)) echo "Yep";
To serialize the data to be stored: $store = serialize($array);
Ten you will be able to create the cookie with $store data and then use unserialize($store) to reconvert data in array.
Serialize Manual
Store array in cookie and then compare them
Here is one out of many solutions (syntax may contain errors):
// Create an array with the values you want to store in the cookie
$id = array(1, 2, 3, 4);
// Create cookie
set_cookie('id', implode(',', $id));
// Get cookie
$id = explode(',', $_COOKIE['id']);
// Test value
if(in_array($newId, $id) === true) {
// Value is in the array
}
Restrictions:
The values stored in $id cannot include commas, choose another separator if you need to store commas

Categories