How to create json string given below - php

I am android developer and new in PHP. I don't know PHP very well. I create
<?php
header('Content-Type: application/json; charset=utf-8');
$mysqli = new mysqli ('localhost', 'mabhi', '9993', 'general');
//PROBLEM LANGUAGE ?????
if (function_exists('mysql_set_charset')) {
mysqli_set_charset($mysqli, 'utf8');
} else {
mysqli_query($mysqli, "SET NAMES 'utf8'");
}
// Check if album id is posted as GET parameter
$myq = $mysqli->query('SELECT * FROM Ages');
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
}
echo json_encode($array, JSON_UNESCAPED_UNICODE);
?>
output:
{
"Questions": [
{
"Question": "sfsa sfd s sdf",
"Answer": "vvv",
"CorrectAnswer": null
},
{
"Question": "dsfgdsfgv dsf dfs",
"Answer": "vvvv vv",
"CorrectAnswer": null
}
]
}
But I would like json output in below format: Answer are displayed multiple times for each question. Please suggest me what changes in my code.
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
{
"Answer": "vvvvvvv"
},
{
"Answer": "vvv"
},
{
"Answer": "vv"
},
{
"Answer": "v"
}
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
{
"Answer": "Lee"
},
{
"Answer": "Wrangler"
},
{
"Answer": "Levi's"
},
{
"Answer": "Diesel"
}
]
}
]
}

As pointed by jereon, you are overwriting the value of Answer key. You need to create a separate array for the all the Answers together.
Change
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
to
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answers' => array((object)array('Answer' => $myr['option1']),
(object)array('Answer' => $myr['option2']),
(object)array('Answer' => $myr['option3']),
(object)array('Answer' => $myr['option4'])),
'CorrectAnswer' => $myr['CorrectAnswer'],
));

You should not assign multiple array elements with the same identifier ("Answer") as they would just overwrite each other. I would suggest you to use a non-associative array for the Answers so that your target JSON would look like this:
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
"vvvvvvv",
"vvv",
"vv",
"v"
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
"Lee",
"Wrangler",
"Levi's",
"Diesel"
]
}
]
}
Therefore you would use the following PHP code for the loop:
$array = array();
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'Answers' => array(
$myr['option1'],
$myr['option2'],
$myr['option3'],
$myr['option4'],
),
);
}

First thing you are doing wrong is you are overwriting the value of answer options so what will happen is when your 1st option will be overwritten by 2nd option, 2nd option with 3rd and 3rd option with 4th option. So you will have to create an array for answers and push every answer in that array and in the end assign this answer option array to answer. So your code should look like below
while ( $myr = $myq->fetch_assoc () ) {
$answers_array=new array();
$answer_option=new stdClass(); // Create a object to format in required format and use this object to store every option of answer
$answer_option->answer=$myr['option1'];
array_push($answers_array,$answer_option);
$answer_option->answer=$myr['option2'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option3'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option4'];
array_push($answers_array,$answer_option);
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'answers' => $answers_array;
);
}

Related

How can I build an object/array?

I am rather new to PHP so I don't know how to work with these datasets. I make a MySQL select and get back an object like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": "7.70"
},
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 3,
"dailyworkhourssum": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
I want to iterate through this and in the end it should look like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid1": true,
"categorid3": true,
"dailyworkhourssum1": "7.70",
"dailyworkhourssum3": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
What this does is that it merges tow fields together (if they have the same bookingdate )into one so that I can display it in a table without reoccurring dates.
My problem:
I don't know what this type of data is called.
I don't know how to create something like this.
I can add fields to this type of data with $data->newField = example so I think that this is an object.
In JS it's called an object, but in PHP you will use an associative array instead.
In your case, I think, you have an array of associative arrays. It looks like this:
$books = [
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 1,
"dailyworkhourssum" => "7.70"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 3,
"dailyworkhourssum" => "1.2"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-05",
"categoryid" => 3,
"dailyworkhourssum" => "7.70"
]
];
If you wanna merge an arrays with the same "bookingdate" then I recommend you to loop through this array and add its elements to another associative array with bookingdates as keys, and check, in case if there is such key already, then merge the arrays, like this:
$merged = [];
foreach ($books as $book) {
$date = $book['bookingdate'];
if (isset($merged[$date])) {
$merged[$date] = $merged[$date] + $book;
} else {
$merged[$date] = $book;
}
}
I think that it is not a valid code (no time, sorry), but I hope, you cautch the idea.
If you want a 'list' instead of an associative array, than you can do this:
$mergedList = array_values($merged);
Thus you will rid of string keys.
If I understood correctly, you obtain a table with 4 columns an a variable number of rows and you want to transform it to a table with a variable number of columns. For that, using a data structure where every item is different from the previous one can make everything harder than it needs. I'd suggest you use a fixed structure:
// I'm assuming you have a PHP array as starting point
$input = [
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 1,
'dailyworkhourssum' => '7.70',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 3,
'dailyworkhourssum' => '1.2',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-05',
'categoryid' => 3,
'dailyworkhourssum' => '7.70',
],
];
$output = [];
foreach ($input as $data) {
// We'll group by booking date
if (!isset($output[$data['bookingdate']])) {
$output[$data['bookingdate']] = [
'membername' => $data['membername'],
'bookingdate' => $data['bookingdate'],
'categoryid' => $data['categoryid'],
'dailyworkhourssum' => [],
];
}
// A single date may have several daily work hours
$output[$data['bookingdate']]['dailyworkhourssum'][] = $data['dailyworkhourssum'];
}
// We discard array keys (we only needed them to group)
echo json_encode(array_values($output));
[{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": ["7.70", "1.2"]
}, {
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": ["7.70"]
}]
Wherever you consume this JSON you just need to loop the dailyworkhourssum array. You may also want to loop the entire structure before printing the table and keep a counter in order to determine the maximum number of columns so you can draw empty cells where needed (tables are rectangular).

Mustache.php rendering multi-dimensional data

I'm utilizing Mustache to template some XML responses for an API. I was wondering how I could use the XML template below to render data from this array?
The data is not rendering at all when using this code:
$result = $m->render($template, $r);
echo $result;
Here is JSON converted data:
[
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"41",
"condition":"A",
"stocknumber":"F0049356",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"U3020",
"comments": "comment for #0"
},
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"68",
"condition":"C",
"stocknumber":"F0048586",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"KEEP"
"comments": "comment for #1"
},
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"280",
"condition":"B",
"stocknumber":"171013",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"YCR4"
"comments": "comment for #2"
}
]
XML template trying to render
$template = '<SupplierResponse>
<QuotedPartList>
{{#parts}}
<QuotedPart>
<BMSObject>
<UUID>{{UUID}}</UUID>
<RefUUID>{{RefUUID}}</RefUUID>
</BMSObject>
<SupplierResponseCode>AsRequested</SupplierResponseCode>
<SupplierRefLineNum>{{SupplierRefLineNum}}</SupplierRefLineNum>
<PartNumInfo>
<PartNumType>Stock</PartNumType>
<PartNum>{{stocknumber}}</PartNum>
</PartNumInfo>
<PartNumInfo>
<PartNumType>IC</PartNumType>
<PartNum>{{ic}}</PartNum>
</PartNumInfo>
<PartType>PAL</PartType>
<PartDesc>{{itemname}}</PartDesc>
<PriceInfo>
<UnitListPrice>{{price}}</UnitListPrice>
<UnitNetPrice>{{price}}</UnitNetPrice>
</PriceInfo>
<RInfo>
<Grade>{{condition}}</Grade>
<DaysInStock>{{daysinstock}}</DaysInStock>
<PartLocation>{{location}}</PartLocation>
<PartStore>{{company}}</PartStore>
</RInfo>
<Availability>
<Quantity>{{quantity}}</Quantity>
<InventoryStatus>Available</InventoryStatus>
<AvailableShipDate>2018-05-10</AvailableShipDate>
</Availability>
<LineNoteInfo>
<LineNoteMemo>{{comments}}</LineNoteMemo>
</LineNoteInfo>
</QuotedPart>
{{/parts}}
</QuotedPartList>
</SupplierResponse>';
Edit: Based on new information that came to light after I posted this answer - your issue occurred because Mustache requires data to be stored in an associative array.
// Not correct
$data = [
[
'Foo' => 'Bar'
],
[
'Biz' => 'Buz'
],
]
// Correct
$data = [
'MyData' => [
[
'Foo' => 'Bar'
],
[
'Biz' => 'Buz'
]
]
]
You could try something like this:
<?php
$objectToPassIn = [
'parts' => [
// .. your data here
]
];
// Load template and initialize Mustache
$m = new Mustache_Engine(array(
'loader' => new Mustache_Loader_FilesystemLoader('path/to/where/template/is/stored', array('extension' => '.xml'))
));
$rendered = $m->render(
'template-name-without-file-extension',
$objectToPassIn
);
Finally got it fixed. The data was not formatted correctly:
Data:
$r = array("parts"=> array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"41",
"condition"=>"A",
"stocknumber"=>"F0049356",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"U3020",
"comments"=> "comment for #0",
"SupplierRefNum"=> 1
),
array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"68",
"condition"=>"C",
"stocknumber"=>"F0048586",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"KEEP",
"comments"=> "comment for #1",
"SupplierRefNum"=> 2
),
array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"280",
"condition"=>"B",
"stocknumber"=>"171013",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"YCR4",
"comments"=> "comment for #2",
"SupplierRefNum"=> 3
}
}
);
Code:
$result = $m->render($template, $r); // Used same template as in my original post.

How to select a field of a contained association as a field of the main entity?

I have Cakephp 3 in a project and I'm doing api rest to get a JSON to get data in mobile devices.
I have two tables in associated with a foreign key like this:
MySql tables
----------------------
Table Tickets:
|id|code|price_id|
Table Prices
|id|price|
----------------------
In TicketsTable CakePHP:
$this->belongsTo('Prices', [
'foreignKey' => 'price_id',
'joinType' => 'INNER'
]);
In controller when I make REST api:
$this->loadModel('Tickets');
$entradas = $this-> Tickets->find('all')
->contain('Prices')
->select(['Tickets.code','Prices.price'])
->limit('200')
->toArray();
Then this array, parsed to JSON return this:
"result":{
"tickets":[
{
"code":"08998112773",
"prices":{
"prices.price":1
}
},
{
"code":"07615265880",
"prices.prices":{ .........
And I want to return this JSON:
"result":{
"tickets":[
{
"code":"08998112773",
"price":1
},
{
"code":"07615265880",
"price":1 .........
That is, that prices do not insert into a new array and that the name of the table does not appear in the field name.
Thanks a lot!!!!
You could use use Cake\Collection\Collection::map() to create a new array:
$tickets = [
'result' => [
'tickets' => [
[
'code' => '123',
'prices' => [
'prices.price' => '2'
]
],
[
'code' => '312423',
'prices' => [
'prices.price' => '4'
]
]
]
]
];
$collection = new Collection($tickets['result']['tickets']);
$new = $collection->map(function ($value, $key) {
return [
'code' => $value['code'],
'price' => $value['prices']['prices.price']
];
});
$result = $new->toArray();
debug(json_encode(['result' => ['tickets' => $new]], JSON_PRETTY_PRINT));
die;
The output is:
{
"result": {
"tickets": [
{
"code": "123",
"price": "2"
},
{
"code": "312423",
"price": "4"
}
]
}
}

How to get data from JSON file by parsing array name from the url

I am trying to print data in json format from my 'data.json' file. With my php file (alldata.php), I could get all data (arrays) pretty printed. But where I want you to help me is how to get a specific array name and it objects/content.
My alldata.php looks like this:
{
"players": [
{
"name": "Marcos Alonso",
"position": "Left-Back",
"nationality": "Spain",
"marketValue": "9,000,000 €",
"created": "2017-04-15 10:04:58"
}],
"articles": [
{
"author": "Stephen Walter",
"title": "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url": "http://www.telegraph.co.uk/news/2017/04/15/disruptive-stag-party-revellers-thrown-plane-manchester-airport/",
"publishedAt": "2017-04-15T09:25:10Z"
}],
land": [
{
"state": "Somewhr",
"found": "1889",
"area": "6,812",
"empl": "1,325",
"ppl": "16,842"
}]
}
In php, how can I get an array e.g "players" with the content by using url such as 'alldata.php?search=players'
Here is a code sample....
//get content of the JSON API using file_get_contents()
$url = ('myJson.json');
$jsondata = file_get_contents($url);
//convert json object to php associative array
$data = json_decode($jsondata, true);
what do I do here to query the data.json file for a specific array?????
header('Content-Type: application/json; charset=UTF-8');
$json_string = json_encode($????????????, JSON_PRETTY_PRINT);
print $json_string;
Thanks
If I properly understood what you mean, and if your array has always the same tree, this wilp help you access the data :
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
$array = array(
0 => array(
"players" => array(
"name" => "Marcos Alonso",
"position" => "Left-Back",
"nationality" => "Spain",
"marketValue" => "9,000,000 €",
"created" => "2017-04-15 10:04:58"
),
"articles" => array(
"author" => "Stephen Walter",
"title" => "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url" => "http://www.telegraph.co.uk/news/2017/04/15/",
"publishedAt" => "2017-04-15T09:25:10Z"
),
"land" => array(
"state" => "Somewhr",
"found" => "1889",
"area" => "6,812",
"empl" => "1,325",
"ppl" => "16,842"
)
),
1 => array(
"players" => array(
"name" => "Sebastian Vettel",
"position" => "Driver",
"nationality" => "Germany",
"marketValue" => "9,000,000 €",
"created" => "2013-03-15 11:04:52"
),
"articles" => array(
"author" => "Stephen Walter",
"title" => "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url" => "http://www.telegraph.co.uk/news/2017/04/15/",
"publishedAt" => "2017-04-15T09:25:10Z"
),
"land" => array(
"state" => "Somewhr",
"found" => "1889",
"area" => "6,812",
"empl" => "1,325",
"ppl" => "16,842"
)
)
);
/* end of array */
$data1 = json_encode($array); /* just checking - not needed after that */
$data = json_decode($data1, true); /* just checking - not needed after that */
$needle = "articles"; /* should be $needle = $_GET['search']; and checked before use */
//print_r($data); /* just checking */
foreach($data as $value){ /* we access 1st level */
echo '** Needle is: '.$needle.' **<br/>';
foreach($value[$needle] as $sub_key => $sub_data){ /* we access 2nd level */
echo $sub_key.'-->'.$sub_data.'<br/>'; }
}
?>
Once you access the data, you can easily do what you want with it...

How do I remove nested object from an object in CakePHP?

CakePHP API returns result like this:
{
"status": "OK",
"themes": [
{
"Theme": {
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
}
]
}
I would like to ask, how can in remove nested Theme object to get result like this?:
{
"status": "OK",
"themes": [
{
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
]
}
Here is my CakePHP code:
$this->Theme->recursive = -1;
// GET USER ID
$themeData['user_id'] = $isSessionValid;
// GET ALL THEMES RELATED TO USER
$foundThemes = $this->Theme->find('all', array(
'conditions' => array(
'Theme.user_id' => $themeData['user_id'])
)
);
$themes = array();
// FOREACH THEMES AND GET COUNT FOR CARDS FOR EACH THEME
foreach($foundThemes as $foundTheme) {
// GET COUNT OF QUESTIONS FOR ACTUAL THEME
$countOfCards = $this->Theme->Card->find('count', array(
'conditions' => array(
'Card.theme_id' => $foundTheme['Theme']['id'])
)
);
// APPEND TO ACTUAL ARRAY
$foundTheme['Theme']['count_of_cards'] = $countOfCards;
array_push($themes,$foundTheme);
}
// SET SUCCESS RESPOSNSE
$this->set(array(
'status' => 'OK',
'themes' => $themes,
'_serialize' => array(
'status',
'themes',
)
));
Many thanks for any advice.
You can manipulate CakePHP's array formats using its built in Hash utility: http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash
What I would do would be to flatten the results:
$results = Hash::flatten($results);
Your data array will end up as a single dimensional array looking like this:
$results = array(
'status' => 'OK'
'themes.0.Theme.id' => 20,
...
'themes.1.Theme.id' => 21,
...
);
You can then use string replace to remove "Theme" from your keys:
$keys = array_keys($results);
$keys = str_replace('Theme.', '', $keys);
Then you can use Hash::expand to get your original array, now formatted how you want:
$results = Hash::expand(array_combine($keys, array_values($results)));
I dont think CakePHP supports this. if you want to do this with an easy way check the Set Utility.
http://book.cakephp.org/2.0/en/core-utility-libraries/set.html

Categories