json_encode to produce complex output - php

Up until now I have just used PHP's json_encode() on simple rows of data, for example
{
"name":"bob",
"age":"22"
}
However I have the need to return JSON which has arrays.
Example output is
{
"success":true,
"payload":
{
"venuedata":
{
"id":"1",
"name":"venue name"
},
"menus": [
{"menuid":"1","menuname":"food","items": [{"item":"pizza","cost":"$12.50"},{"item":"burger","cost":"$14.50"}]},
{"menuid":"2","menuname":"drinks","items": [{"item":"pint of beer","cost":"$5.50"}]}
]
}
}
Now, the venuedata object will come from one PDO query, and the menus will come from another query and the items for each menu will come from another query.
How can I use json_encode to return the example JSON?

A generalized example assuming the menu items and the menus are connected to each other with a foreign key.
Create an array of menus and add for every menu element in the array the menu items.
$arrMenus = array();
$menus = getMenusFromDB();
foreach($menus as $menu) {
$menuItems = getMenuItemsFromDB($menu["id"]);
$arrMenuItems = array();
foreach($menuItems as $menuItem){
$arrMenuItems []= array(
"item" => $menuItem["item"],
"cost" => $menuItem["cost"]
);
}
$arrMenus []= array(
"menuid" => $menu["id"],
"menuname" => $menu["menuname"],
"items" => $arrMenuItems
);
}
Then create an array with the rest of the information and add the "menus" array as part of the "payload" array:
$obj = array(
"success" => true,
"payload" => array(
"venuedata" => array(
"id" => "2",
"name" => "venue name"
),
"menus" => $arrMenus
)
)
After convert the array via json_encode():
$json = json_encode($obj);

Related

Foreach array return last value

I'm learning OOP and I whould create a list of objects in an array, but my code return the last array
I have search here, but haven't found a solution or idea how to do this.
Excepct
"MerchantDefinedFields":[
{
"Id":2,
"Value":"email#test.com"
},
{
"Id":4,
"Value":"Web"
},
{
"Id":9,
"Value":"NAO"
},
{
"Id":83,
"Value":"Field"
},
{
"Id":84,
"Value":"Only"
}
]
My code
$MDDs = array(
array("Id" => 2, "Value" => "email#test.com"),
array("Id" => 4, "Value" => "Web"),
array("Id" => 9, "Value" => "NO"),
array("Id" => 83, "Value" => "Field"),
array("Id" => 84, "Value" => "Only")
);
foreach($MDDs as $MDD){
$abac = array("Id" => $MDD['Id'], "Value" => $MDD['Value']);
}
Result
Array
(
[Id] => 84
[Value] => PROPRIO
)
Your foreach() is re-setting $abac every time it goes through the loop. So on the last time it runs, it will set the variable to the last item in your array.
Instead of setting the variable each time, try adding the key->value to an array (or something like that, depending on what you want):
$abac = [];
foreach($MDDs as $MDD){
$abac[] = array("Id" => $MDD['Id'], "Value" => $MDD['Value']);
}
It's hard to create the exact right answer for you, since it's unclear what you're trying to accomplish, but this should at least point you in the right direction.
For simple answer :- You don't need foreach loop to get the desired result
you can simply use built-in php function to convert your array to JSON
$abac = json_encode ( $MDDs);
Now coming to your problem :-
you are re-assigning the $abac variable in loop instead of adding values to it like .
$abac = [];
foreach($MDDs as $MDD){
$abac[] = array("Id" => $MDD['Id'], "Value" => $MDD['Value']);
}
The best way to do it is to declare the $abac outside of the foreach and then use the array_push method like this:
$abac = array();
foreach($MDDs as $MDD)
{
array_push($abac, array("Id" => $MDD['Id'], "Value" => $MDD['Value']));
}
print_r($abac);

How to replace an element in an array

I have a COLLECTION collflokks in MongoDB, sample Document is :-
{
"_id" : "b_8AUL",
"f_name" : "Pizza. Hut",
"f_lat" : "22.7523513",
"f_lng" : "75.9225847",
"c_uid" : "33",
"f_type" : NumberLong(3),
"members" : [
"42",
"43"
]
}
Within the "members" array , I want to add Arrays like {id:42,name:Mark} , {id:43,name:Hughes}
Currently i'm adding just ids(eg.42,43). I'm only concerned about the new data as it will have new ids .Please suggest.
Earlier I was using this code to push into the members Array:
$flokkCollection = 'collFlokks';
$flokkCollection->update(
array("_id" => $f_handle),
array('$push' => array("members" => $u_id))
);
Well if what you are asking here is "replacing your existing data" then you need to "loop" the results from the collection and "replace" the array content that exists with your new format.
There are likely smarter ways to approach this, but you are not really giving us all the required information in your question, so I can only answer in the basic terms.
Presuming you have:
$required = array(
array(array("id" => "42"), array("name" => "Mark")),
array(array("id" => "43"), array("name" => "Hughes"))
);
As input, then you do something like this:
function myMapper($v) {
return $v["id"];
}
$mapped = array_map("myMapper",$required);
foreach( $mapped as $value) {
$filtered = array_values(
array_filter($required,function($k) {
return $k["id"] == $value;
})
)[0];
collection.update(array(
array("members" => $value),
array('$set' => array(
"members.$" => $filtered
))
));
}
Which should use the positional $ operator to find the matched "position" of the array element by the value used in the "query" portion of the update statement, then in the "update" portion of that statement $set that current array index to the new value at the "filtered" content index from the original input array.
Outside of PHP. We call these inner elements "objects" and not "arrays" which is a PHP notation trait. Key/value things are "objects" and "lists" are "arrays".

Building an array of search parameters

I need some help wrapping my head around a problem. I have an array filled with other arrays. I need to:
Loop through the entire array and build a new array called finalOptions
Each iteration of the loop will take a new SearchIndex and apply the other paramenters
i.e
SearchIndex => SportingGoods
MinPercentageOff => 50
MinimumPrice => 1
ItemPage => 1
Sort => salesrank
BrowseNode => 2342470011
THEN:
Final array should contain data like this
SearchIndex => SportingGoods
MinPercentageOff => 60
MinimumPrice => 100
ItemPage => 2
Sort => salesrank
BrowseNode => 3403201
Basically, I'm creating a new array and sending it to another method that will execute a call to an API and return a result, then doing it again until my array options are complete.
This might not be the way to go and I'm looking for suggestions/pseudo code on an approach. Here is the basics of what I have so far:
Starting with this code
$allOptions = array(
"SearchIndex" => array("SportingGoods", "Tools"),
"MinPercentageOff" => array("50", "60", "70"),
"MinimumPrice" => array("1", "100", "1000"),
"ItemPage" => array("1", "2"),
"Sort" => array("salesrank")
"BrowseNode" => array(
"SportingGoods" => array("2342470011", "3403201"),
"Tools" => array("511364")
)
)
$finalOptions = array();
foreach($allOptions as $options){
foreach($options["SearchIndex"] as $searchIndex){
$finalOptions[] = "SearchIndex" => $searchIndex[]
}
$this->itemSearch($finalOptions);
}
EDIT
The arrays will contain more values. i.e "ItemPage" => array("1", "2"), will have 1 - 10. The others will have more values as well.
From the given array it will produce 54 possible combinations as you described.
Also you need to make sure you have array in $allOptions['BrowseNode'] indexed as each value of $allOptions['SearchIndex']. Otherwise it will produce error.
Cartesian function from here.
$allOptions = [
"SearchIndex" => ["SportingGoods", "Tools"],
"MinPercentageOff" => ["50", "60", "70"],
"MinimumPrice" => ["1", "100", "1000"],
"ItemPage" => ["1", "2"],
"Sort" => ["salesrank"],
"BrowseNode" => ["SportingGoods" => ["2342470011", "3403201"], "Tools" => ["511364"] ] ];
$finalOptions = $allOptions; // copy our initial $allOptions array
unset($finalOptions['BrowseNode']); // deal with BrowseNode key later with custom iterator
$cartesian_product = cartesian($finalOptions); // find cartesian except BrowseNode
foreach($cartesian_product as $cartesian) // each member of cartesian product will iterate here
{
foreach($allOptions['BrowseNode'][$cartesian['SearchIndex']] as $possible)
/*
We have unset the BrowseNode, so need to refer original $allOptions array for BrowseNode,
In every cartesian product, we will get $cartesian['SearchIndex'] and it will contain either
'SportingGoods' or 'Tools' , so in our original array, look for 'BrowseNode' value, having key
same as $cartesian['SearchIndex'].
$allOptions['BrowseNode'][$cartesian['SearchIndex']] <---- is similar to below two lines
$key = $cartesian['SearchIndex'];
$allOptions['BrowseNode'][$key];
Finally iterate through $allOptions['BrowseNode'][$cartesian['SearchIndex']] will iterate as many times,
as many values there are
*/
{
$cartesian['BrowseNode'] = $possible; // assign the long waited key here to 'BrowseNode'
var_dump($cartesian); // here you can do $this->itemSearch($cartesian);
}
}
function cartesian($input) {
$input = array_filter($input);
/*
will renove any false values in input array,
in our array's case, it will do nothing.
*/
$result = [[]];
foreach ($input as $key => $values) {
$append = [];
foreach($result as $product) {
foreach($values as $item) {
$product [$key] = $item;
$append [] = $product;
}
}
$result = $append;
}
return $result;
}

PHP & JSON: Inserting an array in a nested array

I am creating a JSON structure to be passed back to Ajax. I would like to insert 'para' => "Hello" into "content" like this:
{
"sections": {
"content": [{
"para": "Hello"
}]
}
}
I tried using this code:
$array = array('sections' => array());
array_push($array["sections"], array("content" => array())); // content must be initialized as empty
array_push($array["sections"][0], array("para" => "Hello"));
But I received this instead:
{
"sections": [{
"content": [],
"0": {
"para": "Hello"
}
}]
}
If I try array_push($array["sections"]["content"], array("para" => "Hello")), I get an error instead. How do I insert an array into "content"? What am I doing wrong?
If I understood your intentions correctly, here's the array structure you're aiming for:
array("sections" => array(
"content" => array("para" => "Hello"),
));
However, in Javascript [] represents an array and {} represents an object. If you're trying to create an object with a property of "0", that's not possible in PHP. Variable names have to start with a letter or underscore.
Here's an array of content objects:
$content = new stdClass();
$content->para = 'hello';
array("sections" => array(
"content" => array($content),
));
To add arrays of contents:
array("sections" => array(
"content" => array(
array("para" => "Hello"),
array("para" => "Hello"),
array("para" => "Hello"),
),
));
You can also construct your own contents array first if you're iterating over an index and then json_encode it. Basic example:
$content = array();
for (i=0; i <3; i++) {
$content[] = array('para' => 'hello');
}
json_encode(array("sections" => array(
"content" => array($content),
)));
To convert that to JSON, put your array inside a json_encode() call.
$array['sections'] = array("content" => array(array("para" => "Hello")));
echo json_encode($array);
will give the result in desired format

Transform string from associative array into multidimensional array

I'm storing images links into the database separating them with ,, but I want to transform this string into an array, but I'm not sure how to do it.
So my array looks like this:
$array = array(
"name" => "Daniel",
"urls" => "http:/localhost/img/first.png,http://localhost/img/second.png"
);
So I'd like to have it in the following form:
$array2 = array(
"name" => "Daniel",
"urls" => array("http:/localhost/img/first.png",
"http://localhost/img/second.png" )
);
I haven't been PHP'ing for a while, but for that simple use-case I would use explode.
$array['urls'] = explode(',', $array['urls']);
Uncertain if I interpreted your question correct though?
You can use array_walk_recursive like in the following example.
function url(&$v,$k)
{
if($k=='urls') {
$v = explode(",",$v);
}
}
$array = array(
"name" => "Daniel",
"urls" => "http:/localhost/img/first.png,http://localhost/img/second.png"
);
array_walk_recursive($array,"url");
You can check the output on PHP Sandbox

Categories