Iterate over KEYLESS JSON array? - php

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.

Related

PHP - Associative array is stored as regular array by foreach loop when containing only 2 values

I've created a form that lets users input measured temperatures at a specific interval, let's say 0 minutes and 1 minutes. This data is sent through by an AJAX call to our server, which in turn returns a function to handle the request.
The function will retrieve the target data from the database - stored as a JSON. When the required data is found, the function will 'unpack' the JSON and alter the specific data. However, eventhough I need the user input to be stored in an associative array, somehow the input gets saved as a regular array.
The specific code that alters the data looks something like underneath:
foreach($list as $list => &$items){
if(isset($items[$item_id])){
if($temperature != ''){
$items[$item_id][$temp_type][(string) $minute] = (float)$temperature;
}else{
unset($items[$item_id][$temp_type][(string) $minute]);
}
}
}
The data that is sent through looks something like this:
AJAX CALL 1
$item_id = 101;
$temp_type = 'hot';
$minute = (int)0;
$temperature = (float)26.5;
AJAX CALL 2
$item_id = 101;
$temp_type = 'hot';
$minute = (int)1;
$temperature = (float)55.5;
I'm expecting the following output in my database:
"101":{"hot":{"0":26.5,"1":55.5},
However, what I receive is:
"101":{"hot":[26.5,55.5],
Important info:
Whenever I send more than 2 AJAX requests to the server - i.e. when the user form contains more than 2 fields ranging between 0 - X minutes - the associative array keeps its form and everything is just fine.
So what I don't quite get at the moment, is why $items[$item_id][$temp_type][(string) $minute] = (float)$temperature; reverts the data back to a regular array?

Access serialized Array in php - WORDPRESS POSTMETA

I have a serialized array that I need to access:-
a:5:{s:5:"width";i:750;s:6:"height";i:330;s:4:"file";s:25:"2017/12/Sophrologie-1.jpg";s:5:"sizes";a:21:{s:20:"listingpro-blog-grid";a:4:{s:4:"file";s:25:"Sophrologie-1-372x240.jpg";s:5:"width";i:372;s:6:"height";i:240;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-blog-grid2";a:4:{s:4:"file";s:25:"Sophrologie-1-372x330.jpg";s:5:"width";i:372;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-blog-grid3";a:4:{s:4:"file";s:25:"Sophrologie-1-672x330.jpg";s:5:"width";i:672;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:23:"listingpro-listing-grid";a:4:{s:4:"file";s:25:"Sophrologie-1-272x231.jpg";s:5:"width";i:272;s:6:"height";i:231;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro-listing-gallery";a:4:{s:4:"file";s:25:"Sophrologie-1-580x330.jpg";s:5:"width";i:580;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-list-thumb";a:4:{s:4:"file";s:25:"Sophrologie-1-287x190.jpg";s:5:"width";i:287;s:6:"height";i:190;s:9:"mime-type";s:10:"image/jpeg";}s:23:"listingpro-author-thumb";a:4:{s:4:"file";s:23:"Sophrologie-1-63x63.jpg";s:5:"width";i:63;s:6:"height";i:63;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb1";a:4:{s:4:"file";s:25:"Sophrologie-1-458x330.jpg";s:5:"width";i:458;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb2";a:4:{s:4:"file";s:25:"Sophrologie-1-360x198.jpg";s:5:"width";i:360;s:6:"height";i:198;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb3";a:4:{s:4:"file";s:25:"Sophrologie-1-263x198.jpg";s:5:"width";i:263;s:6:"height";i:198;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb4";a:4:{s:4:"file";s:25:"Sophrologie-1-653x199.jpg";s:5:"width";i:653;s:6:"height";i:199;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-detail_gallery";a:4:{s:4:"file";s:25:"Sophrologie-1-383x330.jpg";s:5:"width";i:383;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:33:"listingpro-checkout-listing-thumb";a:4:{s:4:"file";s:24:"Sophrologie-1-220x80.jpg";s:5:"width";i:220;s:6:"height";i:80;s:9:"mime-type";s:10:"image/jpeg";}s:31:"listingpro-review-gallery-thumb";a:4:{s:4:"file";s:25:"Sophrologie-1-184x135.jpg";s:5:"width";i:184;s:6:"height";i:135;s:9:"mime-type";s:10:"image/jpeg";}s:17:"listingpro-thumb4";a:4:{s:4:"file";s:25:"Sophrologie-1-272x300.jpg";s:5:"width";i:272;s:6:"height";i:300;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location270_400";a:4:{s:4:"file";s:25:"Sophrologie-1-270x330.jpg";s:5:"width";i:270;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location570_455";a:4:{s:4:"file";s:25:"Sophrologie-1-570x330.jpg";s:5:"width";i:570;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location570_228";a:4:{s:4:"file";s:25:"Sophrologie-1-570x228.jpg";s:5:"width";i:570;s:6:"height";i:228;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location270_197";a:4:{s:4:"file";s:25:"Sophrologie-1-270x197.jpg";s:5:"width";i:270;s:6:"height";i:197;s:9:"mime-type";s:10:"image/jpeg";}s:22:"listingpro_cats270_213";a:4:{s:4:"file";s:25:"Sophrologie-1-270x213.jpg";s:5:"width";i:270;s:6:"height";i:213;s:9:"mime-type";s:10:"image/jpeg";}s:22:"Sophrologie-1-1170x400";a:5:{s:4:"file";s:25:"Sophrologie-1-1170x400jpg";s:5:"width";s:4:"1170";s:6:"height";s:3:"400";s:9:"mime-type";s:10:"image/jpeg";s:7:"nova-wp";b:1;}}s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:19:"Maygutyak - Fotolia";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"0";s:8:"keywords";a:0:{}}}
I want to retrieve the Sophrologie-1-1170x400jpg filename from it (at the bottom of the array).
I can't figure out how to retrieve this filename into this array. The clue is that there is a nova-wp value in that row.
This array comes fromwp-postmeta table in an wordpress installation.
If you could bring me to the direction, I'll be very thankful.
The data you show has been produced through serialization. Use the unserialize function in order to bring it back to its original state:
$data = unserialize($text);
Then, traverse the deserialized data it in order to retrieve the value you are looking for:
echo $data["sizes"]["Sophrologie-1-1170x400"]["file"];
// Output: Sophrologie-1-1170x400jpg
A working demo can be found here.
If you need to scan your data in order to find the correct value, you can use the following code:
$data = unserialize($text);
if (array_key_exists("Sophrologie-1-1170x400", $data["sizes"])) {
echo $data["sizes"]["Sophrologie-1-1170x400"]["file"];
} else {
echo "File not found!";
}

save a multidimensional array to txt

Hi I have an array that stores products. Here is an example of the first product:
$_SESSION['pricebook']['product1'] = array(
'name' => 'product1',
'description'=>'Board my Cat(s)!',
'price'=>25.95,
);
And I have an array for the cart that stores each product a user selects from the pricebook array.
if(!isset($_SESSION['cart'])){
$_SESSION['cart'] = array();
}
How would I write the cart into an orders.txt file? Everything I have tried has given me the "Array Notice: Array to string conversion" error.
Note: the product is added to the cart as so:
if (isset($_GET["product1"]) && $_GET["product1"]=="Add") {
$pid = $_GET["name"];
if (!isset($_SESSION['cart'][ $pid ])) { $_SESSION['cart'][ $pid ]; }
array_push($_SESSION['cart'][ $pid ]);
}
Also is there any way that it can be saved to a txt file in a human readable format kinda like a receipt?
You can use PHP's serialize() for this.
Generates a storable representation of a value.
This is useful for storing or passing PHP values around without losing their type and structure.
To make the serialized string into a PHP value again, use unserialize().
To save, your code could look like this
$representation = serialize($_SESSION['cart']);
// save $representation to your txt file/whatever
and to load the values, just do as is said in the manual
// load data into $representation
$_SESSION['cart'] = unserialize($representation);
If you want a prettier format, you can use json_encode() with the JSON_PRETTY_PRINT flag set
$representation = json_encode($_SESSION['cart'], JSON_PRETTY_PRINT);
// save $representation to your txt file/whatever
// load data into $representation
$_SESSION['cart'] = json_decode($representation);
You could try:
$handle = fopen('orders.txt', 'w+'); // change this based on how you would like to update the file
fwrite($handle, print_r($_SESSION['cart']), true);
fclose($handle);
Use either serialize or json_encode.
You could use serialize() like this
$t = serialize($_SESSION['cart']);
file_put_contents('filename.txt', $t);
Or json_encode()
$t = json_encode($_SESSION['cart']);
file_put_contents('filename.txt', $t);
serialize will work a tiny little bit faster, but is PHP specific, while json_encode will produce a JSON string that can be fed into anything, including a toaster :D The JSON string also leaves a smaller footprint than the serialized one.

Google API JSON Postal Code with PHP in Address Object

I want go get the adress details from a JSON return like:
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false
But the Array always differs in the amount of elements. So any Idea how to get the adress details like postal code with php?
This should work for you if you want to retrieve the postal_code. It should give you the idea of how to access the other data you require:
// Decode json
$decoded_json = json_decode($json);
foreach($decoded_json->results as $results)
{
foreach($results->address_components as $address_components)
{
// Check types is set then get first element (may want to loop through this to be safe,
// rather than getting the first element all the time)
if(isset($address_components->types) && $address_components->types[0] == 'postal_code')
{
// Do what you want with data here
echo $address_components->long_name;
}
}
}
Just a little addition to the answer provided by Springie. If you want to loop through the whole array, you'll need to add another condition, because you might end up with getting only prefix of the post code.
if ( isset($address_components->types)
&& $address_components->types[0] === 'postal_code'
&& !in_array('postal_code_prefix', $address_components->types) ) { }

How to filter JSON array into PHP array

I have a JSONArray generated in java and I post it to one of my PHP files where it's saved to a file. From there it gets read and I need to generate a chart based on this data. All I need is to convert my raw JSON which has values I don't need, into a simply php array.
[{"id":1,"timestamp":"1363135091","reward":1200,"player":"Orangeguy24","address":"108.28.239.167","service":"MC-Index"},{"id":2,"timestamp":"1363135091","reward":1200,"player":"Orangeguy24","address":"108.28.239.167","service":"MC-Index"}]
Is an example of 2 elements inside my JSON array. What I need todo is filter those values into arrays accordingly.
For example get how many votes a 'player' has, I need to add up how ever many elements are in the JSONArray, because 1 element is 1 vote (the id is primary auto-increment in my mysql DB, not located on my webserver)
I'd like the array to be to [player, votes] so when I echo the array it will be easily parsed by the google chart tools I'm using. I've spent the last 5 hours working on this and I've been stuck, thanks for any help!
To decode the JSON into a php array, you can do:
$json_array = json_decode($raw_json);
Then, to get the number of votes for each player out of the array:
$player_votes = array_reduce($json_array,
function($v, $item) {
if(!array_key_exists($item->player, $v))
$v[$item->player] = 1;
else
$v[$item->player] = 1 + $v[$item->player];
return $v;
}, array());
If I understand your question correctly, this will work.
EDIT: Updated the second code snippet
Try this :
$str = '[{"id":1,"timestamp":"1363135091","reward":1200,"player":"Orangeguy24","address":"108.28.239.167","service":"MC-Index"},{"id":2,"timestamp":"1363135091","reward":1200,"player":"Orangeguy24","address":"108.28.239.167","service":"MC-Index"}]';
$res = array();
foreach(json_decode($str,true) as $val){
if(array_key_exists($val['player'],$res)){
$res[$val['player']] = $res[$val['player']]+1;
}
else{
$res[$val['player']] = 1;
}
}
echo "<pre>";
print_r($res);
Output :
Array
(
[Orangeguy24] => 2
)

Categories