mysql返回多级数组

时间:2012-08-22 12:09:33

标签: php mysql multidimensional-array

我正在使用三个与PHP应用程序相关的MySQL表。有些测试有很多问题,问题有很多答案。我想做的是循环数据如下:

foreach($tests as $test)
{
    echo $test->testName;

    foreach($test->questions as $question)
    {
        echo $question->questionText;

        foreach($question->answers as $answer)
        {
            echo $answer->answerText;
        }
    }
}

我想知道的是MySQL查询和PHP代码将以这种方式循环通过它?

编辑 MySQL无法返回这样的数组,我应该说的是MySQL + PHP代码的样子。

为清楚起见,表格是测试,问题和答案。问题表包含test_id列,答案包含question_id

谢谢!

我想要回来的结构将是:

array(
    'testName' = 'Test name string',
    'questions' = array(
        array(
            'questionId' = 1,
            'questionText' = 'Question string',
            'answers' = array(
                array(
                    'answerId' = 1,
                    'answerText' = 'Answer string'
                ),
                array(
                    'answerId' = 2,
                    'answerText' = 'Answer string'
                )
            )
        )
    )
);

修改

我目前的实现如下,我想做的是急于加载数据而不是执行如此多的查询

$tests = getTests();

foreach($tests as $test){

    $questions = getQuestions($test->id);

    foreach($questions as $question){

        $answers = getAnswers($question->id);

        foreach($answers as $answer){

            // do answer things

        }

    }

}

4 个答案:

答案 0 :(得分:3)

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");


$query = "SELECT testname, question, answer
    FROM tests 
    JOIN questions ON (tests.id = question.test_id)
    JOIN answers ON (questions.id = answers.id)
    WHERE 'your condition'
    ORDER BY tests.id, question.id"

$result = $mysqli->query($query);

您可以使用in_array函数来获得所需的结果(您可以创建数组或打印结果)。以下是打印值的示例。 (你可以使用id代替名称来改善)

$tests_arr = array();
$questions_arr = array();

while( $row = $result->fetch_array(MYSQLI_ASSOC) )
{
    if(!in_array($row['testname'], $test_arr)
    {
        $test_arr[] = $row['testname'];
        echo $row['testname'];
    }

    if(!in_array($result['question'], $question_arr))
    {
        $questions_arr[] = $row['question'];
        echo $row['question'];
    }

    echo $row['answer'];
}

答案 1 :(得分:1)

MySQL无法以您希望的格式返回数组结构 - 它能做的最好的是用于表示列/行的2D数组。

两种替代方案都将在PHP中实现。

  1. 为每个测试运行查询;遍历每个测试并运行查询以获得此测试的所有问题;遍历每个问题并运行查询以获得此问题的答案。
  2. 示例:

    // get each test
    $tests = array();
    $results = $mysqli->query('SELECT id, name FROM tests;');
    while ($test = $results->fetch_object()) $tests[] = $test;
    foreach ($tests as $t => $test) {
        // get all questions for this test
        $tests[$t]['questions'] = array();
        $results = $mysqli->query('SELECT id, name FROM questions WHERE test_id = ' . $test['id']);
        while ($question = $results->fetch_object()) $tests[$t]['questions'][] = $question;
        foreach ($tests[$t]['questions'] as $q => $question) {
            // get all answers for this question
            $tests[$t]['questions'][$q]['answers'] = array();
            $results = $mysqli->query('SELECT id, name FROM answers WHERE question_id = ' . $question['id']);
            while ($answer = $results->fetch_object()) $tests[$t]['questions'][$q][] = $answer;
        }
    }
    


    2.使用MySQL连接运行单个查询,并预先迭代结果列表,以您希望的格式构建数组。

答案 2 :(得分:1)

在纯SQL中你可以做一个连接,但这会让你得到扁平的行,行数就是测试*问题*答案。然后,您必须解析属性并将其映射到适当的对象。像这样:

$sql = "SELECT * FROM tests t, questions q, answers a  WHERE q.t_id = t.id AND a.q_id = q.id";
$rows = // do your fetching, pdo, mysqli, whatever, just get the rows

$tests = array();
foreach($rows as $row) {
    // map test
    if(!isset($tests[$row['t_id']])) $tests[$row['t_id']] = array(
       // set test attributes here (without the questions)
    );

    // map question
    if(!isset($tests[$row['t_id']]['questions'][$row['q_id']])) = array(
       // set question attributes here (without the answers)
    );

    // map answer
    if(!isset($tests[$row['t_id']]['questions'][$row['q_id']]['answers'][$row['a_id']])) = array(
       // set answer attributes here 
    );
}

$ tests数组现在应该具有您需要的层次结构, 但一定要测试一下,但即使它不起作用,你也会明白这一点。

话虽如此,看看一些ORM-s。 对于其中一个最简单的(以一种好的方式),看看这个: http://phpmaster.com/database-interaction-made-easy-with-notorm/

本教程非常容易理解,最后您可以得到您所要求的内容,一组具有属性的对象以及基于表关系的良好层次结构。

答案 3 :(得分:0)

你会LEFT JOIN以便结果如下:

test1|question1|answer1
test1|question1|answer2
test1|question2|answer1
test1|question2|answer2
test2|question1|answer1

然后以这样的方式遍历它,它们总是按顺序循环,所以编写一个取回行的循环,如果测试自上一次以来已经改变,则移动到数组中的下一个测试。重复问题,最后添加答案。

一些伪代码

fetcharray()
if test > lasttest
  arraytest++
  arrayquestion = 0
elif question > lastquestion
  arrayquestion++

array[arraytest][arrayquestion][] = fetched array