Critter
Critter

Reputation: 1018

How do I retrieve results as multidimensional array from mySQL and PHP?

I'm just starting to learn more advanced SQL along with PHP and I'm really struggling trying to find out how to query my database for a quiz I'm building.

Ultimately, I'm trying to return a json object with the following structure which gives me a list of questions and all possible answers as a multidimensional array:

{
    "questions":
        [
            {
                "question": "question text here",
                "answers":
                    [
                         { "answer": "answer text here", "points": 10 },
                         { "answer": "answer text here", "points": 20 },
                         { "answer": "answer text here", "points": 30 },
                         { "answer": "answer text here", "points": 40 }
                    ]
            },
            {
                "question": "question text here",
                "answers":
                    [
                         { "answer": "answer text here", "points": 10 },
                         { "answer": "answer text here", "points": 20 },
                         { "answer": "answer text here", "points": 30 },
                         { "answer": "answer text here", "points": 40 }
                    ]
            }
        ]
{

...from my mySQL tables of the following structure:

quiz

id | title
1  | quiz title here

quiz_question

id | quiz_id (FK) | question_text
1  |       1      | question text here
2  |       1      | question text here

quiz_answer

id | quiz_question_id (FK) | answer_text      | points
1  |            1          | answer text here |   10
2  |            1          | answer text here |   20
3  |            1          | answer text here |   30
4  |            1          | answer text here |   40

...with the following foreign keys:

quiz_question.quiz_id is FK to quiz.id
quiz_answer.quiz_question_id is FK to quiz_question.quiz_id

...using the following PHP (in it's simplest form which is currently only returning my questions):

//query the db
$query = mysql_query("
    SELECT quiz_question.question_text
    FROM quiz_question
    JOIN quiz ON quiz.id = quiz_question.quiz_id
    WHERE quiz.id = 1;
");

$numrows = mysql_num_rows($query);
for ($i = 0; $i < $numrows; $i++) {
    $row = mysql_fetch_assoc($query);
    $quiz_data[$i] = array("question" => $row["question_text"]);
}

//echo JSON to page
$response = $_GET["jsoncallback"] . "(" . json_encode($quiz_data) . ")";
echo $response;

...and using jQuery's $.getJSON() in my JavaScript which gets my a JSON formatted object from my PHP which gets me back the following:

[
    {"question":"question text here"},
    {"question":"question text here"}
]

So my question is, how can I write my SQL and PHP to create a multidimensional array like the very above instead of a single array like I'm currently getting back now? I need to figure out how to include the questions and all associated answers as a multidimensional array.

Upvotes: 5

Views: 10047

Answers (4)

john smith
john smith

Reputation: 13

The previous answers will all boast greater performance than what I'm about to suggest, but this article offers a flexible solution for "joined" results, especially as nested joins build off one another.

PHP Rebuild Database Result Array

Run the result through json_encode() to convert it to a JSON object.

Upvotes: 0

Explosion Pills
Explosion Pills

Reputation: 191739

You can't retrieve a multi-dimensional array purely with mysql (at least as far as I know). You will have to do some php processing. This doesn't sound too crazy.

First, update your query to select answers at the same time by joining quiz_answers on quiz_questions using the question ID. Then, in your loop:

$quiz = array();
while ($row = mysql_fetch_assoc($result)) {
   // you don't need to check num_rows
   // fetch_assoc returns false after the last row, so you can do this
   // which is cleaner
   if (!isset($quiz[$row['question_id'])) {
      $quiz[$row['question_id']] = array(
         'question' => $row['question_text']
         , 'answers' => array()
      );
   }
   $quiz[$row['question_id']]['answers'][] = $row['answer_text'];
}
$full = json_encode(array('questions' => $quiz'));

This will give you the array you want after it's json encoded.

Note that you will end up selecting the question text/id once per each answer, which is inefficient. You can use GROUP_CONCAT on the answers, but the above will still work almost identically, you just have to split the answer string.

I also suggest you use PDO or some other wrapper over mysql_*.

Upvotes: 6

hakre
hakre

Reputation: 197682

You just run your queries and then create a compound data-structure based upon it ($questions); Example:

$questions= array();

$rowsQuestions = $gateway->findQuestions($quiz);

foreach($rowsQuestions as $row)
{
    $questions[$row->id] = new stdClass;
    $questions[$row->id]->question = $row->question_text;
}

$rowsAnswers = $gateway->findAnswers($quiz);

foreach($rowsAnswers as $row)
{
    $answer = (object) array(
        'answer' => $row->answer_text,
        ...
    );
    $questions[$row->quiz_question_id]->answers[] = $answer;
}

Upvotes: 1

Dustin Graham
Dustin Graham

Reputation: 2086

As far as I know, you'll need to build the multi-dimensional array after pulling the results from the database.

You could probably do a join on the questions and answers, so the resulting array would look something like this:

$results = array(
    array( 'question' => 'question 1', 'answer' => 'answer 1', 'points' => 10 ),
    array( 'question' => 'question 1', 'answer' => 'answer 2', 'points' => 30 ),
    array( 'question' => 'question 2', 'answer' => 'answer 1', 'points' => 20 ),
    array( 'question' => 'question 2', 'answer' => 'answer 2', 'points' => 50 )
);

Then from there you could build your json array by grouping the questions and answers together.

Basically, php and the standard mysql_query functions won't build the multi-dimensional arrays, so you'll have to pull the data and build it yourself.

Upvotes: 1

Related Questions