PHP - 循环 & lastInsertId()

PHP - loop & lastInsertId()

我有这段代码可以对问题、选择和多项选择执行插入操作 table。我设法完成了插入问题和选择table,但我没有做到的是多项选择table。

require("dbOption/Db.class.php");
$question       =   new Db();
$choice         =   new Db();
$multichoice    =   new Db();
$entries = array(
    0 => '1. What foo?',
    1 => 'a. foo1',
    2 => 'b. foo2',
    3 => 'c. foo3',
    4 => 'd. foo4',
    5 => '2. 2 + 2 is?',
    6 => 'a. test1',
    7 => 'b. test2',
    8 => 'c. test3',
    9 => 'd. test4',
);

$answerIDs    = "";
$questionID   = "";

$multipleChoice = array();

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        echo "<pre>";
            var_dump($entry);
        echo "<pre>";
        $question->query("INSERT INTO question(q_name) VALUES(:question)",array("question"=>$entry));
        $questionID = $question->lastInsertId();
    } else {
        echo "<pre>";
            var_dump($entry);
        echo "<pre>";
        $answer->query("INSERT INTO choice(choices,question) VALUES(:choices, :question)",array("choices"=>$entry, "question"=>$questionID));
        if ($answerIDs === "")
            $answerIDs = $choice->lastInsertId();
        else
            // store last inserted ids in choice table and separate it with ","
            $answerIDs .= ("," . $choice->lastInsertId());
    }
}

这是数据库中的示例输出。

问题table

id     q_name
1   1. What foo?
2   2. 2 + 2 is?

选择table

id   choices    question  correct
1   a. foo1        1       0
2   b. foo2        1       0
3   c. foo3        1       0
4   d. foo4        1       0
5   a. test1       2       0
6   b. test2       2       0
7   c. test3       2       0
8   d. test4       2       0

question in choice table is the id from question table

我想在多项选择中实现什么 table。

多选table

 id  question  mc_answers
  1    1        1,2,3,4
  2    2        5,6,7,8

多选table中的问题问题[=53]中的id =]

我很迷茫,请教各位大侠。我应该怎么做才能实现这一目标?

正如我所说,我认为您根本不应该存储这些列表。存储逗号分隔值通常被认为是糟糕的设计,此外,您已经在数据库中拥有了所需的所有信息,因此这些信息也将是多余的。

如果你无论如何都想这样做,我认为有四种解决方案。

1) 开始新题时插入答案。 缺点是循环后必须再次做同样的事情以保存上一题的选择。代码的结构如下所示(为简洁起见,进行了精简)。

$answerIDs = "";

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        if ($answerIDs !== "") {
            // First insert multi select answers

            // Reset the answers for the new question.
            $answerIDs = "";
        }

        // Then insert question as you do now.
    } else {
        // Insert answers and store ID in $answerIDs as you do now.
    }
}

if ($answerIDs !== "") {
    // Store answers (again).
}

2) 将 ID 保存在一个大数组中,然后再存储它们。 您可以将答案保存在嵌套数组中。主层的关键是问题ID。每个问题你存储一个数组(或一个字符串,但我认为数组更容易)的答案。插入问题和答案后,可以循环遍历数组,插入所有的多项选择。

这应该可以正常工作,除非您有数百万个问题。最终 $allAnswerIDs 可能会变得对内存来说太大,但我认为在这种情况下这不会很快成为问题。

$allAnswerIDs = array();

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        // Insert question as you do now.

        // Store the question ID in the array.
        $allAnswerIDs[$questionId] = array();
    } else {
        // Insert answer.

        // Store ID in $answerIDs as an array (or as a string, if you like).
        $allAnswerIDs[$questionID][] = $answerID;
    }
}

foreach ($allAnswerIDs as $questionID => $questionAnswerIDs) {
    // Build a string of the answers per question.
    $answerIDs = implode(',', $questionAnswerIDs);

    // Insert the multiple choice row using $questionID and $answerIDs.
}

3) 在循环后使用批量插入。 您可以编写一个稍微复杂一点的 SQL 语句,一次性插入所有这些语句,例如:

INSERT INTO multichoice(question, mc_answers)
SELECT
  question,
  GROUP_CONCAT(choices) as AnswerIDs
FROM
  Choice

您可以在脚本末尾执行一次该语句,它会使数据库一次性生成多项选择的全部内容table。

4) 发表看法。 可以看到,方法3中的(相对简单的)select在多选table中显示了你想要的所有信息,所以与其将它插入到table中,你可以考虑使其成为数据库中的视图。这样,您根本不必存储信息。您的 PHP 代码会更简单,您的数据库会更干净,并且您可以像从 table.

中一样从视图中查询