【问题标题】:Inserting from a multidimensional associative array into multiple tables using PHP and MySQL使用 PHP 和 MySQL 从多维关联数组插入到多个表中
【发布时间】:2015-11-09 21:04:33
【问题描述】:

我在这两天的大部分时间里都没有取得太大进展。我在这里和其他地方找到了大量帮助,但不知道如何让它们一起发挥作用。

我正在为我在网上找到并想要保存的食谱开发一个简单的数据库。

通过解析 URL 以获取食谱详细信息,然后进行一些手动修剪、添加和编辑来填充表单。每个食谱都有一些基本信息、一些成分和一组说明。它们进入三个不同的表,并且都通过“recipe_id”连接。

我遇到的问题是我不知道如何从 from 和中获取数组:

  • 将一些字段作为一行放入一个表中

  • 将 3 部分成分以多行形式放入另一个表中

  • 最后将指令放入第三个表中作为几行。

这是表单中的 $_POST:

array(47) { 
["title"]=> string(33) "Hot and Fruity Caribbean Coleslaw" 
["description"]=> string(11) "Lorem ipsum" 
["credits"]=> string(11) "Lorem ipsum" 
["url"]=> string(69) "http://thehappyfoodie.co.uk/recipes/hot-and-fruity-caribbean-coleslaw" 
["category"]=> string(1) "1" 
["cuisine"]=> string(1) "1" 
["yield"]=> string(10) "8 servings" 
["time_prep"]=> string(2) "10" 
["time_cook"]=> string(2) "10" 
["time_total"]=> string(2) "20"
["ingredient_quant_0"]=> string(0) "" 
["ingredient_uom_0"]=> string(1) "8" 
["ingredient_0"]=> string(17) "1/2 Savoy cabbage" 
["ingredient_quant_1"]=> string(0) "" 
["ingredient_uom_1"]=> string(2) "11" 
["ingredient_1"]=> string(17) "1/2 white cabbage" 
["ingredient_quant_2"]=> string(0) "" 
["ingredient_uom_2"]=> string(1) "-" 
["ingredient_2"]=> string(21) "1/2 red onion, peeled" 
["ingredient_quant_3"]=> string(0) "" 
["ingredient_uom_3"]=> string(1) "8" 
["ingredient_3"]=> string(15) "1/2 small mango" 
["ingredient_quant_4"]=> string(0) "" 
["ingredient_uom_4"]=> string(1) "-" 
["ingredient_4"]=> string(20) "3 tsp French mustard" 
["ingredient_quant_5"]=> string(0) "" 
["ingredient_uom_5"]=> string(1) "-" 
["ingredient_5"]=> string(19) "100ml cider vinegar" 
["ingredient_quant_6"]=> string(0) "" 
["ingredient_uom_6"]=> string(1) "-" 
["ingredient_6"]=> string(29) "8 tbsp soft light brown sugar" 
["ingredient_quant_7"]=> string(3) "100" 
["ingredient_uom_7"]=> string(2) "10" 
["ingredient_7"]=> string(15) "100ml olive oil" 
["ingredient_quant_8"]=> string(0) "" 
["ingredient_uom_8"]=> string(1) "-" 
["ingredient_8"]=> string(15) "Salt and pepper" 
["ingredient_quant_9"]=> string(1) "1" 
["ingredient_uom_9"]=> string(1) "9" 
["ingredient_9"]=> string(54) "1/2 tbsp X Hot Reggae Reggae Sauce or hot chilli sauce" 
["ingredient_quant_10"]=> string(0) "" 
["ingredient_uom_10"]=> string(1) "-" 
["ingredient_10"]=> string(48) "2 red chillies, seeded and cut into fine slivers" 
["instruction_0"]=> string(177) "Remove and discard the cabbage cores and finely shred the leaves. Slice the onion wafer-thin using a mandolin if you have one. Peel the mango and cut the flesh into matchsticks." 
["instruction_1"]=> string(265) "Put the mustard, vinegar and sugar in a jam jar. Screw on the lid and give it a good shake. Add the oil, salt, pepper and hot sauce. Shake again then poor into a large serving bowl. Toss in the cabbage, onion, mango and chillies and mix well. Taste for seasoning." 
["image"]=> string(127) "https://flockler.com/thumbs/sites/192/127_grillitlevi_hotandfruitycoleslaw-smaller_s1200x630_c1500x876_l0x482_q80_noupscale.jpg" 

然后我将该数组传递给一个函数,并尝试将其分解为应放入不同表的部分:

function addnewrecipe($postArray) {
    var_dump($postArray);


    // Test and clean user input
    $cleanedArray = array();
    foreach ($postArray as $postKey => $postValue) {
        $cleanValue = test_input($postArray[$postKey]);
        $cleanedArray[$postKey] = $cleanValue;
    }

    // Map form post names to those in the DB
    $mappingArray = array(
        'title' => 'name',
        'description' => 'description',
        'credits' => 'author',
        'url' => 'url',
        'category' => 'category_id',
        'cuisine' => 'cuisine_id',
        'yield' => 'yield',
        'time_prep' => 'preptime',
        'time_cook' => 'cooktime',
        'time_total' => 'totaltime',
        'image' => 'image'
    );

    // Create a final array with used form fields and clean input
    $finalArray = array();
    foreach($mappingArray as $formKey => $dbKey) {
        if(!empty($cleanedArray[$formKey])) {
            $finalArray[$dbKey] = $cleanedArray[$formKey];
        }
    }




    //Connect to DB
    $conn = connDB();

    // Begin transaction
    try {

        $conn->autocommit(FALSE); 

        $recipeKey = array_keys($finalArray);
        $recipeValue = array_values($finalArray);
        $query = "INSERT INTO recipes (" . implode(', ', $recipeKey) . ") " . "VALUES ('" . implode("', '", $recipeValue) . "')";
        //echo $query;
        $result = $conn->query($query);
        if ( !$result ) {
            $result->free();
            throw new Exception($conn->error);
        }

        $recipe_id = $conn->insert_id; // last auto_inc id from *this* connection

        //$query = "INSERT INTO ingredients (recipe_id,ingredient,uom_id,ingredient_quant) ";
        //$query .= "VALUES ('$recipe_id','$ingredient')";
        //$result = $conn->query($query);
        //if ( !$result ) {
        //  $result->free();
        //  throw new Exception($conn->error);
        //}

        $conn->commit();
        $conn->autocommit(TRUE); // i.e., end transaction
    }
    catch ( Exception $e ) {

        $conn->rollback(); 
        $conn->autocommit(TRUE); // i.e., end transaction   
    }

    $conn->close();

虽然我觉得我稍微复杂了一点,但它对于基本信息来说还可以。我首先检查输入中是否存在不安全的内容,然后将表单中的键/列名称重新映射到数据库中的名称,并创建一个新数组$finalArray,其干净的结果省略了说明和成分。

然后进入标准的 INSERT 语句,我可以继续准备插入成分和说明。但这是我自己困惑的地方。

每个食谱都有不同数量的成分。每种成分都有三个值,其中两个可以为 NULL。它们将由上一个插入的“recipe_id”引用,它可以正常工作,如下所示:$recipe_id = $conn->insert_id; 但我怎样才能获得每种成分的三个值并将它们作为一行插入?我试过了

$ingredientArray = array();
    $i = 0;
    while ($i < 5) {
        if (isset($cleanedArray["ingredient_" . $i])) {
            $ingredientArray["ingredient_" . $i] = $cleanedArray["ingredient_" . $i];
        }

        if (isset($cleanedArray["uom_id_" . $i])) {
            $ingredientArray["uom_id_" . $i] = $cleanedArray["uom_id_" . $i];
        }

        if (isset($cleanedArray["ingredient_quant_" . $i])) {
            $ingredientArray["ingredient_quant_" . $i] = $cleanedArray["ingredient_quant_" . $i];
        }
     $i++;
     }
     //var_dump($ingredientArray);

让他们出去,但不知道可能有多少,我猜这种方法相当可疑。

我觉得这不应该那么难。我有一个相当简单的数组,其中包含值以及将数组拆分并将其插入到正确的表中的看似简单的任务。任何有关如何解决此问题的帮助将不胜感激!

【问题讨论】:

  • 困难在于如何组织数据。如果您有权访问应用程序的其他部分,请重新组织数据以帮助您编程。成分应该在它自己的数组节点中,并且在成分节点中,每个成分都有一个成分数组,其中包含您所说的 3 个字段。
  • 您应该以&lt;input type="text" name="ingredient[1][name]" /&gt; &lt;input type="text" name="ingredient[1][quant]" /&gt; &lt;input type="text" name="ingredient[1][uom]" /&gt; 的形式为您的成分使用数组,这将对您有很大帮助
  • 我认为你不应该有像“1/2 savoy cabbage”这样的值。你应该有像“开胃白菜”这样的成分和数量(如 1/2)。可能还有一个单位列(在这种情况下为空或空白,但包含“tsp”、“tbp”等)

标签: php mysql arrays multidimensional-array sql-insert


【解决方案1】:

而不是像您当前一样依靠字符串操作来确定哪种成分属于哪个领域:

array(
    // .... some other stuff above
    "ingredient_quant_0"    =>  "" 
    "ingredient_uom_0"  =>  "8" ,
    "ingredient_0"          => "1/2 Savoy cabbage" ,
    "ingredient_quant_1"    =>  "blah" ,
    "ingredient_uom_1"  =>  "11" ,
    "ingredient_1"          => "1/2 Ricotta Cheese" ,
    "ingredient_quant_2"    =>  "" ,
    "ingredient_uom_2"  =>  "12" ,
    "ingredient_2"          => "2 Chilis" ,
)

构建您的帖子数据,以便将成分组合在一起,如下所示:

array(
    // .... some other stuff above
    "ingredients" => array(
        [0] => array( "quant" => "", "uom" => "8", "ingredient" => "1/2 Savoy cabbage"),
        [1] => array( "quant" => "blah", "uom" => "11", "ingredient" => "1/2 Ricotta Cheese"),
        [2] => array( "quant" => "", "uom" => "12", "ingredient" => "2 Chilis"),
    ) 
 )

HTML 应该是这样的:

<input type="text" name="ingredients[0]['ingredient']>
<input type="text" name="ingredients[0]['uom']>
<input type="text" name="ingredients[0]['quant']>
<hr>
<input type="text" name="ingredients[1]['ingredient']>
... 

然后您可以更轻松地构建插入语句

<?php
$recipe_id = $conn->insert_id; // last auto_inc id from *this* connection
foreach($myPostArray['ingredients'] as $ingredient){
    $query .= "INSERT INTO ingredients (recipe_id,ingredient,uom_id,ingredient_quant) ";
    $query .= "VALUES ( $recipe_id, {$ingredient['ingredient']}, {$ingredient['uom']}, {$ingredient['quant']})";
}
$result = $conn->query($query);

【讨论】:

  • 是的,将每种成分放在自己的数组中是有意义的。但据我了解,当数组是表单提交的结果时,我无法选择如何构造数据?或者我可以吗?
  • 是的,如果您有权访问该表格,您可以。你呢?
  • 在您的插入示例中,我是否会为每种成分创建一个查询,然后一个接一个地运行它们?
  • 不,只需构建长 sql 字符串并立即运行查询。否则你会多次调用你的数据库,这 = 更慢
  • 是的,我可以完全访问该表格。那么我可以直接在表单中指定所需的数组结构吗?像这样:&lt;input type='text' name='ingredients[$i]' /&gt;
【解决方案2】:
$ingredientArray = [];
$i = 0;
while ($i < 5) {
    $ingredientArray[] = [
        'name' => isset($cleanedArray["ingredient_" . $i]) ? $cleanedArray["ingredient_" . $i] : null,
        'quantity' => isset($cleanedArray["ingredient_quantity_" . $i]) ? $cleanedArray["ingredient_quantity_" . $i] : null
        // etc.
    ];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多