Create a desired JSON format using data stored in PHP - php

So I have a bunch of arrays inside which I have all the data I require to pass to a third party app. Problem is that they need it in a specific JSON format, and I do not have an idea how I can do that. The data format they require is like:
{
"appData" : {
"appKey" : "blah blah",
"synth" : {
"synth1" : {
"mono" : [
{
"monoId" : "529",
"templates" : [
{
"monoSequenceMap" : [
{
"map" : {
"X" : "3",
"Y" : "1"
},
"position" : {
"scale" : "1",
"x1" : "100",
"x2" : "150",
"y1" : "2000",
"y2" : "2500"
}
},
{
"map" : {
"X" : "2",
"Y" : "4"
},
"position" : {
"scale" : "1",
"x1" : "200",
"x2" : "550",
"y1" : "1000",
"y2" : "1500"
}
},
{
"map" : {
"X" : "3",
"Y" : "3"
},
"position" : {
"scale" : "1.5",
"x1" : "300",
"x2" : "750",
"y1" : "1750",
"y2" : "1800"
}
},
{
"map" : {
"X" : "4",
"Y" : "1"
},
"position" : {
"scale" : "1.5",
"x1" : "680",
"x2" : "790",
"y1" : "1950",
"y2" : "1850"
}
}
],
"templateId" : "01_A_19"
}
]
}
],
"synthId" : "XXXXXXXXXX"
}
}
}
}
I just want some pointers on how to convert the data I have into this JSON string. I think I need to use json_encode. Should I create a new class called 'appData' class then create each object/array inside it? or should I just write a string in this format into a text file?
My problem is that I cannot wrap my head around having all these objects inside objects thing...like for e.g, in the JSON synth is an object which contains synth1, synth2 etc which will be objects which in turn will have mono which will be an array of objects...And I am not sure how to tackle that..
Any pointers is greatly appreciated!

Are your arrays multidimensional? Like:
$array = array(
"data_table_1" => array(
"item1" => "Item 1",
"item2" => "Item 2"
),
"data_table_1" => array(
"item1" => "Item 1",
"item2" => "Item 2"
)
);
If so, all you have to use is use json_encode and that will do all the encoding for you:
$json = #json_encode($array);
==== Edit ====
arrays do not have to be multidimensional. Even an array with a single key => value will work. Just be sure you have keys for values, so they're registered correctly.

Related

yii2 mongodb update embedded array

How to update members age whose name is TEST1 using yii2.?
Used below code to update , but i am specifying the indexes there , i want with out specifying the indexes.
User::updateAll([ '$set'=> ['Addresses.0.members.0.age'=>100] ],['IN','Addresses.members.name',['TEST1'] ]);
{
"_id" : ObjectId("595209b65312f48195fb2e01"),
"username" : "Test name",
"Addresses" : [
{
"address_no" : 1,
"Address" : "Test house",
"City" : "test city",
"State" : "Test state",
"Mobile" : "9999999",
"members" : [
{
"name" : "TEST1",
"age" : 35
},
{
"name" : "TEST2",
"age" : 30
},
]
},
{
"address_no" : 2,
"Address" : "2B, Test place",
"City" : "Test city",
"State" : "Test State",
"Pincode" : "12345",
"Phone" : "1234568789",
"Mobile" : 9999999999
}
],
"Beneficiaries" : [
{
"beneficiary_id" : 1,
"Name" : "Test1",
"Age" : "28",
"Sex" : "F"
}
],
"auth_key" : "esd8d89ds89ds89ds89ds",
}
there is position operator $ to do this kind of job
{
"Addresses.members.name" : "TEST2",
},
{
$set: {
"Addresses.$.members.0.age" : 40
}
}
Here I specified first index as it supports up to one level depth.
New feature might release in future to resolve this issue: https://jira.mongodb.org/browse/SERVER-831
Yii::$app->mongodb->getCollection('user')->update(['_id' => $id, 'members.name' => 'Test1'], ['$set' => [
'members.$.age' => 100,
]]);

Retrieve elements using $slice

My result is following after executing find() query.
{
"_id" : ObjectId("5384928a03ea2e75268b4567"),
"0" : {
"name" : "mango",
"quantity" : "10"
},
"1" : {
"name" : "apple",
"quantity" : "14"
},
"2" : {
"name" : "banana",
"quantity" : "11"
},
"3" : {
"name" : "grapes",
"quantity" : "19"
},
"4" : {
"name" : "lichi",
"quantity" : "13"
},
"5" : {
"name" : "orange",
"quantity" : "10"
},
"6" : {
"name" : "lemon",
"quantity" : "10"
},
"7" : {
"name" : "pear",
"quantity" : "10"
},
"8" : {
"name" : "cherry",
"quantity" : "10"
},
"9" : {
"name" : "kiwi",
"quantity" : "10"
}
}
Now i want only any five elements in result(like from 2nd element to 6th element).
How to do this using $slice or is there any other method to retrieve only five elements in result?
The important thing here is, do you actually have an array for $slice to work on? There seems to be a bit of a misconception here common to people working with PHP as the way that language typically represents an array.
The mongo shell ( for example ) will show the clear distinction, where an array actually looks like this in it's JSON representation:
{
"_id" : ObjectId("5384928a03ea2e75268b4567"),
"arrayField": [
{
"name" : "mango",
"quantity" : "10"
},
{
"name" : "apple",
"quantity" : "14"
},
{
"name" : "banana",
"quantity" : "11"
},
{
"name" : "grapes",
"quantity" : "19"
}
]
}
That structure can use the $slice operator to return the elements you want. As an example here, 2 documents from index position 1
db.collection.find({},{ "arrayField": { "$slice": [ 1,2] }})
{
"_id" : ObjectId("5384928a03ea2e75268b4567"),
"arrayField" : [
{ "name" : "apple", "quantity" : "14" },
{ "name" : "banana", "quantity" : "11" }
]
}
The structure you are showing is just a bunch of key names for sub-documents within the top level document. It is probably a mistake but you just specify those fields in the projection. It's not an array so $slice does not apply:
db.collection.find({}, { "1": 1, "2": 1, "3": 1, "4": 1, "5": 1, "6": 1 })
But that probably is not what you want, so it looks like you will need to fix your data so it is an array.
$slice is used to control the number of elements in an array returned by the query, but I don't see an explicit array in your results. Your document should look something like:
{
"_id" : ObjectId("5384928a03ea2e75268b4567"),
"fruit" : [
{
"name" : "mango",
"quantity" : "10"
},
{
"name" : "apple",
"quantity" : "14"
}
]
}
Then you could query it with something like:
db.collection.find({},{"fruit": {$slice:[1:6]}})
If you want to get only 5 record from document you can use limit(), if you want to skip few of the record then use skip().
For Example :
db.collection.find().skip(2).limit(5);
This query fetch 5 documents after first 2 documents.

Parse HTML in PHP and return JSON

I am using PHP Simple HTML DOM Parser in my PHP script to parse information from a website into a JSON object. My JSON object should be formatted like this in the end:
Array with maximum 5 objects (Monday to Friday) or less (Tuesday–Friday etc).
All of these objects should have two arrays, one called food1 and one called food 2. Both of these arrays should contain multiple food names and their prices. I think in JSON it would look like this:
{
"day" : [
{
"food1" : [
{
"price" : "1.00",
"foodname" : "test"
},
{
"price" : "1.00",
"foodname" : "test"
}
],
"food2" : [
{
"price" : "2.00",
"foodname" : "test2"
},
{
"price" : "2.00",
"foodname" : "test2"
}
]
},
{
"food1" : [
{
"price" : "1.00",
"foodname" : "test"
},
{
"price" : "1.00",
"foodname" : "test"
}
],
"food2" : [
{
"price" : "2.00",
"foodname" : "test2"
},
{
"price" : "2.00",
"foodname" : "test2"
}
]
},
{
"food1" : [
{
"price" : "1.00",
"foodname" : "test"
},
{
"price" : "1.00",
"foodname" : "test"
}
],
"food2" : [
{
"price" : "2.00",
"foodname" : "test2"
},
{
"price" : "2.00",
"foodname" : "test2"
}
]
},
{
"food1" : [
{
"price" : "1.00",
"foodname" : "test"
},
{
"price" : "1.00",
"foodname" : "test"
}
],
"food2" : [
{
"price" : "2.00",
"foodname" : "test2"
},
{
"price" : "2.00",
"foodname" : "test2"
}
]
},
{
"food1" : [
{
"price" : "1.00",
"foodname" : "test"
},
{
"price" : "1.00",
"foodname" : "test"
}
],
"food2" : [
{
"price" : "2.00",
"foodname" : "test2"
},
{
"price" : "2.00",
"foodname" : "test2"
}
]
}
]
}
Anyway I previously only worked with Objective-C and having problems with solving this problem in PHP. I have also implemented a parser in Objective-C that works, but if the site changes their structure I would have to re-submit the whole app etc. That’s why I wanted to make a web service where I can dynamically change the parser outside of the app. All I got is this:
<?php
include('simple_html_dom.php');
$opts = array('http'=>array('header' => "User-Agent:MyAgent/1.0\r\n"));
$context = stream_context_create($opts);
$html = file_get_html('http://www.studentenwerk-karlsruhe.de/de/essen/?view=ok&STYLE=popup_plain&c=erzberger&p=1&kw=3',false,$context);
foreach($html->find('b') as $e)
echo $e;
?>
Which gives me all the food names but it isn’t sorted for the days and also not for the different food menus (there are two different menus on each day which are called food1 and food2 in my example JSON object).
In my Objective-C parser I just created a new day object when the food name is “SchniPoSa” and added all the following food names to food1 until there comes the food name “Salatbuffet” that and all the following food names I added to food2 array until there comes the next “SchniPoSa” food name. But this isn’t very good because the structure could change every day.
Also, I do not even know how to implement that in PHP. In my little PHP script I also don’t parse all the prices which are in the tag <span class="bgp price_1">.
Here is the website from which I want to parse the information:
http://www.studentenwerk-karlsruhe.de/de/essen/?view=ok&STYLE=popup_plain&c=erzberger&p=1&kw=3
Is there anyone who can help me with parsing the information in a valid JSON object like I described below?
Just saw you message and realised I hadn't gotten back to you about this.
Maybe this will lead you in the right direction:
<?php
$opts = array('http'=>array('header' => "User-Agent:MyAgent/1.0\r\n"));
$context = stream_context_create($opts);
$html = file_get_contents('http://www.studentenwerk-karlsruhe.de/de/essen/?view=ok&STYLE=popup_plain&c=erzberger&p=1&kw=3',false,$context);
libxml_use_internal_errors(true);
$dom = new DomDocument;
$dom->loadHTML($html);
$xpath = new DomXPath($dom);
$nodes = $xpath->query("//table[#class='easy-tab-dot']");
//header("Content-type: text/plain");
foreach ($nodes as $i => $node) {
$arr = array();
$children = $node->childNodes;
foreach ($children as $child) {
$tmp_doc = new DOMDocument();
$tmp_doc->appendChild($tmp_doc->importNode($child,true));
#echo $tmp_doc->saveHTML();
print_r( $child );
}
echo "#######################################################################################";
}

Can't find proper criteria to update document in mongoDB

I have followed model stored in mongoDB:
{
"_id" : "some_table_name",
"content" : [{
"id" : "1",
"locname" : "KKH"
}, {
"id" : "2",
"locname" : "Singapore National Eye Centre"
}]
}
I try to find criteria to update 2nd element (id=2) aka add new String.
"new_element" : "foo"
So new view should be:
{
"_id" : "some_table_name",
"content" : [{
"id" : "1",
"locname" : "KKH"
}, {
"id" : "2",
"locname" : "Singapore National Eye Centre"
"new_element" : "foo"
}]
}
Form PHP
When I try to find 2nd node by id I use:
$array = $collection_bios2->findOne(
array("_id" => "some_table_name", "content.id" => "2"),
array("_id" => 0, "content.$" => 1)
);
But when I try to update it, new node enters under content:
$newdata = array('$set' => array("new_element" => "foo"));
$collection_bios2->update(
array("_id" => "some_table_name", "content.id" => "2"),
$newdata
);
I get:
{
"_id" : "some_table_name",
"content" : [{
"id" : "1",
"locname" : "KKH"
}, {
"id" : "2",
"locname" : "Singapore National Eye Centre"
}],
"new_element" : "foo"
}
Whats wrong in my implementation?
Please, help,
Maxim
You need to use the positional operator here:
array('$set'=>array('content.$.new_element':'foo'))
You can read more about it here: http://docs.mongodb.org/manual/reference/operator/positional/

count JSON multidimendional array in php

i got this json format form form-builder plugin, in hope someone could help out i need to count the number of times certain fields occur so i can create a database for them
[ { "cssClass" : "checkbox",
"required" : "false",
"title" : "hello save",
"values" : { "2" : { "baseline" : "false",
"value" : "save"
},
"3" : { "baseline" : "false",
"value" : " save 2"
},
"4" : { "baseline" : "false",
"value" : "save 3"
},
"5" : { "baseline" : "false",
"value" : "save 4"
},
"6" : { "baseline" : "false",
"value" : "save 5 "
},
"7" : { "baseline" : "false",
"value" : "Save 6"
}
}
},
{ "cssClass" : "textarea",
"required" : "false",
"values" : "you did not say hello properly"
},
{ "cssClass" : "checkbox",
"required" : "false",
"title" : "whats up save",
"values" : { "2" : { "baseline" : "false",
"value" : "i got your back"
},
"3" : { "baseline" : "false",
"value" : "i got your back 2"
},
"4" : { "baseline" : "false",
"value" : "i got your back 3"
},
"5" : { "baseline" : "false",
"value" : "1 got your back 4"
},
"6" : { "baseline" : "false",
"value" : "i got your back 5"
}
}
}
]
i want to be able to count the number of cssClass checkbox and the corresponding values value to help create a database table for insert in mysql or mongodb
i will like it in a format like this
count($data[cssclass])
count($data[cssClass][values])
i get
Notice: Undefined index: cssClass in C:\wamp\www\callme\repo\index.php on line 45
i will appreciate any solution in php or nodejs sice am quite new to Json
!============================================================================!
Hello guys, thanks for your timely response, i appreciate and feel very privileged to have u guy but it didn't really solve the challenge maybe i was not clear enough so this is the program logic. for the given json data i will like to sort it in a way that i can get the tile of the checkbox and its values which to create database entries for the user e.g
for array with checkbox get title and number of values (value) so i can have something like say
checkbox1 title values = 6
checkbox2 title values = 5
The JSON Object in your example is an Array. You can either use the following code to count all of the values:
$total = 0;
foreach($data as $row){
$total += count($row['values']);
}
or you can use the following to reach one object:
count($data[0]['values']);
Of course you'll need to use
json_decode($json_string,true)
to convert your json object into a PHP array.
You never deal with "json objects" directly. JSON is just a text string that happens to represent a javascript-style data structure. You always deal with NATIVE data structures, so
$array = json_decode($your_json);
$count = count($array['cssclass']);
Is what you'd do in PHP - convert to a native PHP array/object, then do your counting on that.
And as for what you should be counting on, once you've decoded back to native PHP, you can examine the actual structure with
var_dump($array);
This should get you there:
<?php
$json = '[{"cssClass":"checkbox","required":"false","title":"hello save","values":{"2":{"value":"save","baseline":"false"},"3":{"value":" save 2","baseline":"false"},"4":{"value":"save 3","baseline":"false"},"5":{"value":"save 4","baseline":"false"},"6":{"value":"save 5 ","baseline":"false"},"7":{"value":"Save 6","baseline":"false"}}},{"cssClass":"textarea","required":"false","values":"you did not say hello properly"},{"cssClass":"checkbox","required":"false","title":"whats up save","values":{"2":{"value":"i got your back","baseline":"false"},"3":{"value":"i got your back 2","baseline":"false"},"4":{"value":"i got your back 3","baseline":"false"},"5":{"value":"1 got your back 4","baseline":"false"},"6":{"value":"i got your back 5","baseline":"false"}}}]';
$obj = json_decode($json, true);
$cssClasses = array_filter($obj, function($el){ return $el["cssClass"] == "checkbox" });
print_r($cssClasses);
I think with a loop you will get out what you want (but I am not 100% sure if I understand you correctly).
<?php
$json = '[ { "cssClass" : "checkbox", "required" : "false", "title" : "hello save", "values" : { "2" : { "baseline" : "false", "value" : "save" }, "3" : { "baseline" : "false", "value" : " save 2" }, "4" : { "baseline" : "false", "value" : "save 3" }, "5" : { "baseline" : "false", "value" : "save 4" }, "6" : { "baseline" : "false", "value" : "save 5 " }, "7" : { "baseline" : "false", "value" : "Save 6" } } }, { "cssClass" : "textarea", "required" : "false", "values" : "you did not say hello properly" }, { "cssClass" : "checkbox", "required" : "false", "title" : "whats up save", "values" : { "2" : { "baseline" : "false", "value" : "i got your back" }, "3" : { "baseline" : "false", "value" : "i got your back 2" }, "4" : { "baseline" : "false", "value" : "i got your back 3" }, "5" : { "baseline" : "false", "value" : "1 got your back 4" }, "6" : { "baseline" : "false", "value" : "i got your back 5" } } } ]';
// first convert the json string to an array (as the others already said)
$array = json_decode($json);
$boxes = array();
foreach ($array as $obj)
{
if ($obj->cssClass == "checkbox")
{
$boxes[] = array(
"title" => $obj->title,
"count_values" => count( (array)$obj->values ) // cast the object as an array to count the indexes
);
}
}
?>
This will give you a new array, containing only the checkboxes with titles and the number of values.
/*
Array
(
[0] => Array
(
[title] => hello save
[count_values] => 6
)
[1] => Array
(
[title] => whats up save
[count_values] => 5
)
)
*/

Categories