I'm trying to make a form with a bunch of questions which can be added to a radioBox, checkBox etc. I have made a .json file containing the questions and possible answers like this (this is just a small part of the file):
{
"questions": {
"0": {
"question":"How many products?",
"answers":["Less than 1000", "More than 1000", "More than 10000"],
"score":[1, 2, 3],
"info":"This is additional information for question 1"
}
,
"1":{
"question":"How many websites?",
"answers":["One", "Two", "Three"],
"score":[1, 2, 3],
"info":"This is additional information for question 2"
}
}
}
I use a class in which I have several functions to make array's which can be used on my regular .php page. I have made an array of questions using the following piece of code, which works:
$questions = [];
foreach($json['questions'] as $key => $value){
$this->questions[] = $value['question'];
}
Now I can just use question[0] to get the first question and question[1] for the second, which is really nice. What I am trying to do is create an array that contains all the answers per question so I can do something similar with the answers. Ideally, it would look something like this:
array:
arrayQuestion1Answers:
string: answer1
string: answer2
string: answer3
arrayQuestion2Answers:
string: answer1
string: answer2
string: answer3
That way I could do something like arrayQuestion1[0] to get the first answer from the first question, and arrayQuestion2[2] to get the third answer from the second question.
Thank you for reading my long (and possibly stupid) question, hope you can help!
Try this,
$json = '{
"questions": {
"0": {
"question":"How many products?","answers":["Less than 1000", "More than 1000", "More than 10000"],"score":[1, 2, 3],"info":"This is additional information for question 1"
}
,"1":{
"question":"How many websites?","answers":["One", "Two", "Three"],"score":[1, 2, 3],"info":"This is additional information for question 2"
}
}
}
';
$questions = json_decode($json,true);
$question = $questions['questions'];
foreach($question as $key => $que):
$answer['arrayQuestion'.$key.'Answers'] = $que['answers'];
endforeach;
echo '<pre>';
print_r($answer);
You say you already have functions to convert the JSOn to PHP arrays. Have you ever checked out json_decode()? It's a native PHP function to decode your JSON. It returns false on failure.
Furthermore: why are you indexing the objects in your questions object in your JSON? You might as well type:
{
"questions": [
{"somekey": "this_is_question_0"},
{"somekey": "this_is_question_1"}
]
}
That way they're automatically indexed.
To answer you actual question, if you use what I describe above, you can simply access a question's answers like this:
$questions = json_decode($json);
$answers_to_question_1 = $questions[0]['answers'] ?? []; // ?? [] means: if not set, make it an empty array. This is the null coalesce feature, available in PHP 7.0 and higher. See http://php.net/manual/en/migration70.new-features.php.
Related
This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 3 years ago.
The API is returning the following json:
{
"car1": [
{
"car_name": "audi",
"gear_box_type": "Automatic",
"num_of_seats": "2",
"num_of_doors": "3",
"imagePath": "/images/a3.png"
}
]
}
The following is my php code:
<select class="form-control" id="exampleFormControlSelect1">
<?php
$obj = new ApiHelper();
$result = $obj->CallAPI("GET","http://localhost:5000/cars", "NONE");
$jsondata = json_decode($result, true);
$car = $jsondata['car1'];
echo "<option>".$car."</option>";
?>
</select>
The output will be "Array".
Image of select
I would like to know how I can access this array that is inside the json.
Any help much appreciated thanks.
The array is accessed like any standard PHP array. You can Google search "PHP arrays" to find more information. One helpful function is print_r($array_name).
So:
print_r($jsondata);
Will give you a printout of the structure of the array, making it easy for you to then determine what is available to you in the array. If you view the output of this function in your browser, be sure to right-click on the page and select "View Source." Otherwise the structure will be printed out as one long string that isn't very fun to read.
Hope this helps!
I have a JSON file that, in essence, is structured like this:
[{
"name": "James",
"reviews": [
{
"stars": 5,
"body": "great!"
},
{
"stars": 1,
"body": "bad!"
}
]
},
{
"name": "David",
"reviews": [
{
"stars": 4,
"body": "pretty good!"
},
{
"stars": 2,
"body": "just ok..."
}
]
}]
Now when positing new review data for David to a PHP script, how do I target David's specific "reviews" and append it?
I have already decoded everything correctly and have access to both the decoded file and post information. I just don't know how to target David's specific reviews in the JSON array... Thank you in advance!
UPDATE - Just to be clear, everything is decoded already, the POST data and the JSON file from the server. I just need to know how to target David's reviews specifically and append it.
UPDATE 2 - Everyone, please also understand that this is in the case that the index is not known. Doing [1] would be awesome, but when someone submits, they won't know what index it is. The loop for the rendering is being done in AngularJS btw, so can't assign anything on the PHP side for the front-end.
You will have to make use of a for-loop/foreach to iterate through the array testing where arr['name'] === 'David',
then you can access arr['reviews'].
foreach ($array as $person)
{
if ($person['name'] === 'David')
{
$person['reviews'][] = array("stars"=> 3,"body"=> "pretty cool!");
break;
}
}
Edit:
You could also make a generic function for this
function findElem(arr,field,e)
{
foreach ($arr as $elem)
{
if ($elem[field] === e)
{
return $elem;
}
}
return null;
}
to call:
$elem = findElem(myArray,'name','David');
if ($elem !== null)
$elem[] = array("stars"=> 3,"body"=> "pretty cool!");
Looks like more work, but if you are going to do it repeatedly then this helps.
PHP >= 5.5.0 needed for array_column or see below for an alternate:
$array[array_search('David', array_column($array, 'name'))]['reviews'][] = array(
'stars'=>1,'body'=>'meh'
);
Instead of array_column you can use:
array_map(function($v) { return $v['name']; }, $array);
If you want specifically david's reviews, and only david's reviews... assuming that $array holds the json_decoded array:
$david_reviews = $array[1]["reviews"];
foreach($david_reviews as $review){
//Do code to retrieve indexes of array
$stars = $review["stars"] //5
$body = $review["body"] //Great!
}
If you're looking to grab reviews for each result, then user2225171's answer is what you're looking for.
json_decode($json, true) will return you the simple array of data. Then save what you need and save back with json_encode()
I am requesting my output look like this:
Response
{
error_num: 0
error_details:
[
{
"zipcode": 98119
},
{
"zipcode": 98101
}
]
}
The values are irrelevant for this example.
My code looks like this:
$returndata = array('error_num' => $error_code);
$returndata['error_details'] = $error_msg;
$temp_data = array();
$temp_value = '';
foreach ($zipcodes_array as $value) {
//$temp_data['zipcode'] = $value;
//$temp_value .= json_encode($temp_data);
$temp_value .= '{"zipcode":$value},';
}
//$returndata['test'] = $temp_value;
$returndata['zipcodes'] = $temp_value;
echo json_encode($returndata);
My output varies depending on my different attempts (which you can see with the commented out things) but basically, I don't understand how the 3rd part (the part with the zipcodes) doesn't have a key or a definition before the first open bracket "["
Here is the output for the code above:
{"error_num":0,"error_details":"","zipcodes":"{\"zipcode\":11111},{\"zipcode\":11112},{\"zipcode\":11113},{\"zipcode\":22222},{\"zipcode\":33333},{\"zipcode\":77325},{\"zipcode\":77338},{\"zipcode\":77339},{\"zipcode\":77345},{\"zipcode\":77346},{\"zipcode\":77347},{\"zipcode\":77396},{\"zipcode\":81501},{\"zipcode\":81502},{\"zipcode\":81503},{\"zipcode\":81504},{\"zipcode\":81505},{\"zipcode\":81506},{\"zipcode\":81507},{\"zipcode\":81508},{\"zipcode\":81509},"}
Obviously i did not show the variables being filled/created because its through MySQL. The values are irrelevant. Its the format of the output i'm trying to get down. I don't understand how they have the "zipcode": part in between {} brackets inside another section which appears to be using JSON_ENCODE
It is close but see how it still has the "zipcodes": part in there defining what key those values are on? My question is, is the "response" above being requested by a partner actually in JSON_ENCODE format?? or is it in some custom format which I'll just have to make w/out using any json features of PHP? I can easily write that but based on the way it looks in the example above (the response) I was thinking it was JSON_ENCODE being used.
Also, it keeps putting the \'s in front of the " which isn't right either. I know it's probably doing that because i'm json_encode'ing a string. Hopefully you see what i'm trying to do.
If this is just custom stuff made to resemble JSON, I apologize. I've tried to ask the partner but I guess i'm not asking the right questions (or the right person). They can never seem to give me answers.
EDIT: notice my output also doesn't have any [ or ] in it. but some of my test JSON_ENCODE stuff has had those in it. I'm sure its just me failing here i just cant figure it out.
If you want your output to look like the JSON output at the very top of your question, write the code like this:
$returndata = array('error_num' => $error_code);
$returndata['error_details'] = array();
foreach ($zipcodes_array as $value) {
$returndata['error_details'][] = array('zipcode' => (int)$value);
}
echo 'Response ' . json_encode($returndata);
This will return JSON formatted like you requested above.
Response
{
error_num: 0
error_details:
[
{
"zipcode": 98119
},
{
"zipcode": 98101
}
]
}
Can you just use single ZipCode object as associative array, push all your small ZipCode objects to the ZipCodes array and encode whole data structure. Here is the code example:
$returndata = array(
'error_num' => $error_code,
'error_details' => array()
);
foreach ($zipcodes_array as $value) {
$returndata['error_details'][] = array('zipcode' => $value);
}
echo json_encode($returndata);
Recently I had some experience with converting mysql query results into json for a quiz system. Query results contain set of questions and related anwsers to them. The implemented procedure aims to put those questions and answers into multidimensional array and then convert it into json to build quiz db. I've ready to use JS procedure (quiz module) that works with below mentioned JSON structure. But to build this structure I'm stuck with the following php procedure:
Code in PHP:
$query = "SELECT s1.question, s2.answers, s2.correct
FROM `questions` s1, `answers` s2
WHERE s1.id=s2.questionid AND s1.courseid=".$_POST['courseid']."";
$result = mysqli_query($mysqli, $query) or die ("<b>Select failed:</b> ".mysqli_error($mysqli));
$final_quiz = array();
$final_quiz['introduction'] = "Introduction text goes here";
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions']['question'] = $rows['question'];
$final_quiz['questions']['question']['answers'] = array($rows['answers'], "correct"=> $rows['correct']);
}
// convert to JSON
$json = json_encode($final_quiz);
echo $json;
Expected JSON Output:
{
"introduction":"Some introductory text here",
"questions":[
{
"question":"Question number one here?",
"answers":["some incorrect answer", "a correct answer", "another incorrect answer"],
"correct":1}, // indicates an array key that is relates to keys in "answers"
...
]
}
How to organize multidimensional array in order to get above mentioned json structure? Any help would be appreciated.
UPDATES
The values in correct keys are indexes of the answers keys, i.e. if we have "correct":1 that would mean second value of answers key. Correct values for answers that come from MySQL are boolean (TRUE/FALSE). So, before putting all answers in answers_array_key as a set of answers one should remember newly assigned index array for the answer with TRUE value put that index array in correct_array_key as value. An example:
....
"answers":[0:"some incorrect answer", 1:"a correct answer", 2:"another incorrect answer"],
"correct":1}, // this is correct answer key
....
Hope that will that will explain the idea of desired json sturcture mentioned above.
I think this will produce the result you want.
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions'][]= array(
'question' => $rows['question'],
'answers' => array($rows['answers']),
'correct'=> $rows['correct']
);
}
In your code, you are overwriting a single element of that array instead of appending the other questions
You can try to use the php json_encode command. (link on php.net -> http://php.net/manual/it/function.json-encode.php)
The link show some example of array structure. On php.net it says it works with each type of structure (not resources).
Edit: as i see you already use this command, but how is the actual output? How much is different from your desired one?
I believe this will solve it for you (I've used an array to test, I hope I got the question right).
You will need to change the foreach loop back to your while loop.
I might have used a bit of different naming, you might need to change a thing or 2 to match your exact names:
<?php
$tmp = array (
array("question"=> "this is a q", "answer"=>"incorrect", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect1", "correct" => false),
array("question"=> "q1", "answer"=>"correct", "correct" => true),
array("question"=> "q1", "answer"=>"incorrect", "correct" => false),
array("question"=> "q1", "answer"=>"incorrect1", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect1", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect2", "correct" => false),
array("question"=> "this is a q", "answer"=>"correct", "correct" => true),
array("question"=> "this is a q", "answer"=>"incorrect3", "correct" => false)
);
$QAndA = array();
foreach ($tmp as $t){
if (!isset($QAndA[$t['question']]['answers']))
$QAndA[$t['question']]['answers'] = array();
$QAndA[$t['question']]['answers'][] = $t['answer'];
if ($t['correct'])
$QAndA[$t['question']]['correct'] = count($QAndA[$t['question']]['answers']) -1;
}
foreach ($QAndA as $q => $data){
$final_quiz['questions'][] = (object)array("question" => $q,
"answers" => $data['answers'],
"correct" => $data['correct']);
}
$json = json_encode($final_quiz);
echo $json;
?>
Result:
{
"questions": [{
"question": "this is a q",
"answers": ["incorrect", "incorrect1", "incorrect1", "incorrect2", "correct", "incorrect3"],
"correct": 4
}, {
"question": "q1",
"answers": ["correct", "incorrect", "incorrect1"],
"correct": 0
}]
}
I do want to apologize for the naming conventions here and the somewhat brute attitude this code presents, but it is very late here;
Add one counter $i and try the below code:
$i = 0;
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions'][$i] = array(
'question' => $rows['question'],
//'answers' => $rows['answers'], UPDATE THIS LINE
'answers' => array(
'1' => $rows['answers'][1],
'2' => $rows['answers'][2],
'3' => $rows['answers'][3])
// Why I started from index one? if index is consecutive from 0 to n
// will remove the index in JSON, so start indexing from 1 and make some changes in ur code
'correct' => $rows['correct']
);
$i++;
}
this will work
I've been using a few javascript libraries, and I noticed that most of them take input in this form: [{"foo": "bar", "12": "true"}]
According to json.org:
So we are sending an object in an array.
So I have a two part question:
Part 1:
Why not just send an object or an array, which would seem simpler?
Part2:
What is the best way to create such a Json with Php?
Here is a working method, but I found it a bit ugly as it does not work out of the box with multi-dimensional arrays:
<?php
$object[0] = array("foo" => "bar", 12 => true);
$encoded_object = json_encode($object);
?>
output:
{"1": {"foo": "bar", "12": "true"}}
<?php $encoded = json_encode(array_values($object)); ?>
output:
[{"foo": "bar", "12": "true"}]
Because that's the logical way how to pass multiple objects. It's probably made to facilitate this:
[{"foo" : "bar", "12" : "true"}, {"foo" : "baz", "12" : "false"}]
Use the same logical structure in PHP:
echo json_encode(array(array("foo" => "bar", "12" => "true")));
An array is used as a convenient way to support multiple parameters. The first parameter, in this case, is an object.
Question one:
JSON is just a way of representing an object and/or and array as a string. If you have your array or object as a string, it is much easier to send it around to different places, like to the client's browser. Different languages handle arrays and objects in different ways. So if you had an array in php, for example, you can't send it to the client directly because it is in a format that only php understands. This is why JSON is useful. It is a method of converting an array or object to a string that lots of different languages understand.
Question two:
To output an array of objects like the above, you could do this:
<?php
//create a test array of objects
$testarray = array();
$testarray[] = json_decode('{"type":"apple", "number":4, "price":5}');
$testarray[] = json_decode('{"type":"orange", "number":3, "price":8}');
$testarray[] = json_decode('{"type":"banana", "number":8, "price":3}');
$testarray[] = json_decode('{"type":"coconut", "number":2, "price":9}');
$arraycount = count($testarray);
echo("[");
$i = 1;
foreach($testarray as $object)
{
echo(json_encode($object));
if($i !== $arraycount)
{
echo(",");
}
$i += 1;
}
echo("]");
?>
This will take an array of objects and loop over them. Before we loop over them, we output the opening square bracket.
Then, for each object in the array, we output it encoded to JSON plus a comma after each one. We count the number of iterations so that we don't output a comma at the end.