PHP - 循环& lastInsertId()

时间:2015-04-06 06:52:24

标签: php mysql arrays pdo

我有这个代码,它将执行问题,选择和多重表的插入。我设法完成插入问题和选择表,我没有做的是多选表。

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());
    }
}

这是db中的示例输出。

问题表

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

选择表

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
选择表中的

问题问题表中的id

我希望在multichoice表中实现的目标。

多张表

 id  question  mc_answers
  1    1        1,2,3,4
  2    2        5,6,7,8
多张桌子中的

问题问题表

中的id

我对如何做到这一点感到困惑,我想向你们咨询一下。我该怎么做才能实现这个目标?

1 个答案:

答案 0 :(得分:1)

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

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

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

您可以在脚本结束时执行一次此语句,它将使数据库立即为multichoice表生成整个内容。

4)制作视图。 正如您所看到的,方法3中的(相对简单的)select显示了您想要在multichoice表中拥有的所有信息,因此您可以考虑将其作为视图而不是将其插入到表中。数据库。这样,您根本不必存储信息。您的PHP代码将更容易,数据库更清晰,您可以从表中查询。