簡體   English   中英

如何將 html 表單中的多行提交到數據庫表中?

[英]How to submit multiple rows from an html form into a db table?

我想只用 function 插入所有值,我不想多次重寫相同的代碼,但我遇到的問題是這個 function 只插入第一個值(我檢查了輸入名稱並且設置正確)。

$name = htmlspecialchars($_POST["name"]);  
$prix = htmlspecialchars($_POST["prixing"]); 
$prixn = htmlspecialchars($_POST["quantite"]);  
$uniteing = $_POST['unite']; 
$date = date('Y-m-d');
<?php

$servername = "localhost"; 
$username = "root"; 
$password = "test"; 
$dbname = "test";

// Create connection $conn = mysqli_connect($servername, $username, $password, $dbname);

// Check connection if (!$conn) {   die("Connection failed: " . mysqli_connect_error());    }  // 
  variable $date = date('Y-m-d');

$name = htmlspecialchars($_POST["name"]);      
$name1 = htmlspecialchars($_POST["name1"]); 
$prix = htmlspecialchars($_POST["prixing"]);   
$prix1 = htmlspecialchars($_POST["prixing1"]); 
$prixn = htmlspecialchars($_POST["quantite"]); 
$prixn1 = htmlspecialchars($_POST["quantite1"]); 
$uniteing = $_POST['unite'];    
$uniteing1 = $_POST['unite1'];

$name2 = htmlspecialchars($_POST["name2"]);          
$name3 = htmlspecialchars($_POST["name3"]); 
$prix2 = htmlspecialchars($_POST["prixing2"]);       
$prix3 = htmlspecialchars($_POST["prixing3"]); 
$prixn2 = htmlspecialchars($_POST["quantite2"]);     
$prixn3 = htmlspecialchars($_POST["quantite3"]); 
$uniteing2= $_POST['unite2'];   
$uniteing3 = $_POST['unite3'];

$name4 = htmlspecialchars($_POST["name4"]);          
$name5 = htmlspecialchars($_POST["name5"]); 
$prix4 = htmlspecialchars($_POST["prixing4"]);       
$prix5 = htmlspecialchars($_POST["prixing5"]); 
$prixn4 = htmlspecialchars($_POST["quantite4"]);     
$prixn5 = htmlspecialchars($_POST["quantite5"]); 
$uniteing4 = $_POST['unite4'];  
$uniteing5 = $_POST['unite5'];

$name6 = htmlspecialchars($_POST["name6"]);          
$name7 = htmlspecialchars($_POST["name7"]); 
$prix6 = htmlspecialchars($_POST["prixing6"]);       
$prix7 = htmlspecialchars($_POST["prixing7"]); 
$prixn6 = htmlspecialchars($_POST["quantite6"]);     
$prixn7 = htmlspecialchars($_POST["quantite7"]); 
$uniteing6 = $_POST['unite6'];  
$uniteing7 = $_POST['unite7'];

$name8 = htmlspecialchars($_POST["name8"]);          
$name9 = htmlspecialchars($_POST["name9"]); 
$prix8 = htmlspecialchars($_POST["prixing8"]);       
$prix9 = htmlspecialchars($_POST["prixing9"]); 
$prixn8 = htmlspecialchars($_POST["quantite8"]);     
$prixn9 = htmlspecialchars($_POST["quantite9"]); 
$uniteing8 = $_POST['unite8'];  
$uniteing9 = $_POST['unite9'];

$name10 = htmlspecialchars($_POST["name10"]); 
$prix10 = htmlspecialchars($_POST["prixing10"]); 
$prixn10 = htmlspecialchars($_POST["quantite10"]); 
$uniteing10 = $_POST['unite10'];

//end variable 2

function insert($namex, $prixx,$prixnx, $datex, $uniteingx,$conn)
{
    $sql = "INSERT INTO ingredient 
                VALUES ('$namex','$prixx','$prixnx','$datex','$uniteingx')"; 
    $res = mysqli_query($conn, $sql);

    if ($res) { 
        echo "New record created successfully"; 
        mysqli_error($conn); 
    } else {   
        echo "_error_: " . $sql . "<br>" . mysqli_error($conn);
    }
} 

insert($name, $prix,$prixn, $date, $uniteing,$conn); 
insert($name1, $prix1,$prixn1, $date1, $uniteing1,$conn); 
insert($name2, $prix2,$prixn2, $date2, $uniteing2,$conn); 
insert($name3, $prix3,$prixn3, $date3, $uniteing3,$conn); 
insert($name4, $prix4,$prixn4, $date4, $uniteing4,$conn); 
insert($name5, $prix5,$prixn5, $date5, $uniteing5,$conn); 
insert($name6, $prix6,$prixn6, $date6, $uniteing6,$conn); 
insert($name7, $prix7,$prixn7, $date7, $uniteing7,$conn); 
insert($name8, $prix8,$prixn8, $date8, $uniteing8,$conn); 
insert($name9, $prix9,$prixn9, $date9, $uniteing9,$conn); 
insert($name10, $prix10,$prixn10, $date10, $uniteing10,$conn);

header('Location: ../index.html'); ?>

這是我的表格:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="css/style.css">
<meta charset="utf-8">
</head>

<body>
<form action="php/insert-multi-ing.php" method="POST">

<table>
  <tr>
    <th>Nom Ingrédient</th>
    <th>Prix Ingrédient</th>
    <th>Quantite Ingrédient</th>
    <th>Unite</th>
  </tr>
  <tr>
    <td><input type="text" name="name"></td>
    <td><input type="text" name="prixing"></td>
     <td><input type="text" name="quantite"></td>
     <td>

        <select name="unite" id="unites">
          <option value="kg">kg</option>
          <option value="G">G</option>
          <option value="L">L</option>
          <option value="ml">Ml</option>
          <option value="cl">Cl</option>
          <option value="Piece">Piece</option>
        </select>
      </td>
    </tr>
    <tr>
        <td><input type="text" name="name1"></td>
        <td><input type="text" name="prixing1"></td>
        <td><input type="text" name="quantite1"></td>
        <td>

            <select name="unite1" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name2"></td>
        <td><input type="text" name="prixing2"></td>
        <td><input type="text" name="quantite2"></td>
        <td>

            <select name="unite2" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name3"></td>
        <td><input type="text" name="prixing3"></td>
         <td><input type="text" name="quantite3"></td>
        <td>
    
            <select name="unite3" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name4"></td>
        <td><input type="text" name="prixing4"></td>
        <td><input type="text" name="quantite4"></td>
        <td>

            <select name="unite4" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name5"></td>
        <td><input type="text" name="prixing5"></td>
        <td><input type="text" name="quantite5"></td>
        <td>

            <select name="unite5" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name6"></td>
        <td><input type="text" name="prixing6"></td>
        <td><input type="text" name="quantite6"></td>
        <td>

            <select name="unite6" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name7"></td>
        <td><input type="text" name="prixing7"></td>
        <td><input type="text" name="quantite7"></td>
        <td>

            <select name="unite7" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name8"></td>
        <td><input type="text" name="prixing8"></td>
        <td><input type="text" name="quantite8"></td>
        <td>
                
            <select name="unite8" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name9"></td>
        <td><input type="text" name="prixing9"></td>
         <td><input type="text" name="quantite9"></td>
         <td>

            <select name="unite9" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name10"></td>
        <td><input type="text" name="prixing10"></td>
        <td><input type="text" name="quantite10"></td>
        <td>
            
            <select name="unite10" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    </table>

    <button>Ajouter ingrédient</button>
</form>
</body>
</html>

您不應該將表單字段重復為列表name0name1 .. name99而是需要將它們作為數組發送,例如: data[0][name] .. data[99][name]

為了不違反DRY 規則,還可以更好地使用 PHP 生成 HTML ,您會意識到將來何時需要使用重復字段編輯表單:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <meta charset="utf-8">
</head>
<body>
<form action="php/insert-multi-ing.php" method="POST">

    <table>
        <tr>
            <th>Nom Ingrédient</th>
            <th>Prix</th>
            <th>Prix Ingrédient</th>
            <th>Quantite Ingrédient</th>
            <th>Unite</th>
        </tr>
        <?php
        for ($i = 0; $i < 10; $i++) {
            echo "
                <tr>
                    <td><input type='text' name='data[{$i}][name]'></td>
                    <td><input type='text' name='data[{$i}][prix]'></td>
                    <td><input type='text' name='data[{$i}][prixn]'></td>
                    <td><input type='text' name='data[{$i}][quantite]'></td>
                    <td>
                        <select name='data[{$i}][unite]' id='unite_{$i}'>
                            <option>kg</option>
                            <option>G</option>
                            <option>L</option>
                            <option>Ml</option>
                            <option>Cl</option>
                            <option>Piece</option>
                        </select>
                    </td>
                </tr>
            ";
        }
        ?>
    </table>
    <button>Ajouter ingrédient</button>
</form>
</body>
</html>

這是在 PHP 中將其作為多維數組訪問使用准備好的語句插入 DB 的示例。 請記住,我在這里使用 PDO 而不是 mysqli ,我建議您:

<?php
$data = $_POST['data'] ?? null;
if (!is_null($data)) {

    $pdo = new PDO("mysql:host=127.0.0.1;dbname=test;charset=utf8", "yourusername", "yourpassword");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("
        INSERT 
        INTO ingredient (name, prix, prixn, unite, quantite, date) 
        VALUES (:name, :prix, :prixn, :unite, :quantite, NOW())
        ");

    $stmt->bindParam('name', $name);
    $stmt->bindParam('prix', $prix);
    $stmt->bindParam('prixn', $prixn);
    $stmt->bindParam('quantite', $quantite);
    $stmt->bindParam('unite', $unite);

    foreach ($data as $item) {
        
        // Adds some data validation to make sure you won't save million empty rows,
        // also add custom validation for other fields (if any)
                 
        $name = checkValue($item['name']);
        $prix = checkValue($item['prix']);
        $prixn = checkValue($item['prixn']);
        $quantite = floatval($item['quantite']);
        $unite = checkValue($item['unite']);

        if (!is_null($name) && !is_null($prix) && !is_null($prixn) && $quantite > 0) {
            $stmt->execute();
        }
    }
}
/**
 * check if the string value is not null and not empty
 *
 * @param $value
 *
 * @return string|null
 */
function checkValue($value)
{
    return (is_null($value) || trim($value) == '') ? null : $value;
}

請注意,您的代碼很混亂,很可能我在表單中使用了錯誤的列名或字段名,只需修復它即可。 一般來說,這是可行的。

您的代碼受 SQL 注入的約束。 最好使用參數化查詢。 他們負責引用、修復可能包括 SQL 注入等的數據。在重復執行相同的語句時,它們的執行速度也更快。

注意:代碼未經測試,可能需要一些語法檢查和其他更正

<?php

//  Create PDO connection
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

//  Create list of base column names
$colList = array(
    'name',
    'prix',
    'prixn',
    'uniteing'
);
//  Create array to hold column values from $_POST
$val = Array(null,null,null,null);

//  Prepare SQL statement with place holders, be sure to explicitly list the table column names. Substitute the actual column names for those below.
$stmt = $dbh->prepare("INSERT INTO ingredient (`namex`,`prixx`,`prixnx`,`uniteingx`) VALUES (:namex,:prixx,:prixnx,:uniteingx)");

//  Bind each array value to a place holder
$stmt->bindParam(':namex',$val[1]);
$stmt->bindParam(':prixx',$val[2]);
$stmt->bindParam(':prinx',$val[3]);
$stmt->bindParam(':uniteingx',$val[4]);

//  Step through the column name suffix values from the form
for($i=0;$i<=10;$i++) {
    //  Special case for the first (0) value (i.e. no suffix)
    $suffix = $i > 0 ? $i : '';
    //  Load the 5 column values from the post variables into the $val array
    foreach($colList as $colNum, $colName) {
        $val[$colNum] = $_POST[$colName . $suffix];
    }
    //  Execute the SQL statement above with the current values in $val
    $stmt->execute();
}


?>

首先,制作您的 html 表格,使其適合用途並且不違反 html 文檔標准。

  • 您應該在循環內生成輸入字段的行。

  • 您應該使用數組語法聲明每個字段的name屬性,以便在分組子數組中提交行數據——這將使后續處理更加容易。 通過簡單地用[]尾隨字段名稱,您可以避免使用不必要的 php 語法使文件混亂。

  • 單個文檔中不得有重復的id屬性。 您可以將 append 作為id字符串末尾的計數器,但很有可能您根本不需要id聲明——我將省略它們。

  • <option>的文本復制為其value的好處為零。 也可以簡單地省略該屬性聲明。

  • 使用度量單位的白名單,這樣您就不需要一遍又一遍地寫出每個<option>標記。 這將提高腳本的可維護性。

  • 為了改進 UX,使用字段屬性,例如: titleplaceholderpatternminlengthmaxlengthrequired等,以及可能的type="number"來指導用戶如何形成有效條目。 這些簡單的操作不僅有助於防止用戶感到沮喪,而且可以使您的應用程序免於對數據庫進行徒勞的訪問和/或僅存儲部分提交。

     <table> <tr> <th>Nom Ingrédient</th> <th>Prix Ingrédient</th> <th>Quantite Ingrédient</th> <th>Unite</th> </tr> <?php $numberOfRows = 10; $units = ['kg', 'G', 'L', 'ml', 'Cl', 'Piece']; for ($i = 0; $i < $numberOfRows; ++$i) {?> <tr> <td><input type="text" name="name[]"></td> <td><input type="text" name="price[]"></td> <td><input type="text" name="quantity[]"></td> <td> <select name="unit[]"> <option><?php echo implode('</option><option>', $units); ?></option> </select> </td> </tr> <?php }?> </table>

至於您的數據庫表設置,這里有一些提示:

  • 避免像date這樣模糊的列命名。 將該列重命名為insert_datecreated_on或類似名稱,以便該值對您的腳本/項目的未來讀者提供更多信息。
  • 修改ingredients表的架構,將insert_date的 DEFAULT 值設置為 CURRENT_DATE。 這樣做時,您永遠不需要將此列寫入您的 INSERT 查詢——當您不為該列傳遞值時,數據庫將自動使用當前日期。
  • 如果此表沒有 AUTOINCREMENTing id列,則應添加一個並將其設為 PRIMARY KEY。 這是一種非常基本的技術,可以改善未來與表的交互,並且當您發現有人向表中提交了重復name時,可以消除可能的混淆。

至於處理您提交的數據,只需幾個簡單的步驟:

  1. 迭代$_POST數組並隔離要插入數據庫的每一行數據。

  2. 隔離后,您需要在執行查詢之前驗證並選擇性地清理每一行,以便您永遠不會在表中存儲“壞數據”。

  3. 您正在使用mysqli ,這很好——您不需要切換到 pdo 來編寫安全/穩定的代碼。 4 您只需生成一次准備好的語句並將變量綁定到占位符一次。 只有語句的(條件)執行需要在循環內。 (其他一些例子: 1 , 2 , 3

  4. 但是,我建議您從 mysqli 的過程語法切換到其面向對象的語法。 它更簡潔,我發現它更易於閱讀。

     // create a mysqli connection object eg $mysqli = new mysqli(...$credentials); $sql = "INSERT INTO ingredients (`id`, `name`, `price`, `quantity`, `unit`) VALUES (NULL, ?, ?, ?, ?)"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('sdds', $name, $price, $quantity, $unit); // Assumes price and quantity are float values $failures = []; $affectedRows = 0; $units = ['kg', 'G', 'L', 'ml', 'Cl', 'Piece']; foreach ($_POST['name'] as $index => $name) { // adjust the validation/sanitization processes as you wish $name = trim($name); $price = trim($_POST['price'][$index]); $quantity = trim($_POST['quantity'][$index]); $unit = trim($_POST['unit'][$index]); $rowNo = $index + 1; if (,strlen($name) ||;strlen($price) ||;strlen($quantity) ||;in_array($unit; $units)) { $failures[] = "Missing/Invalid value on row $rowNo": } elseif (;$stmt->execute()), $failures[] = "A syntax error has occurred", // check your error logs } else { ++$affectedRows, } } echo "Affected Rows; $affectedRows"; if ($failures) { echo "<ul><li>" , implode('</li><li>', $failures) , "</li></ul>"; }

一些總體建議:

  1. 避免混合你的法語和英語。 如果要使用法語變量名,請使用所有法語變量。 也就是說,我已經閱讀了以英語為母語的人和以英語為第二語言的開發人員的建議,他們 state 應該始終在代碼中使用所有英語——這是一場辯論,我現在不會對此發表意見.
  2. 何時使用 htmlspecialchars() function? 您會注意到,在我的回答中,我從未將其稱為 function。 這是因為我們絕不會將用戶的任何輸入打印到屏幕上。 證實? 是的。 消毒? 當然。 HTML 編碼? 沒有; 不是這里,不是現在。
  3. 如果這些成分行與特定的recipe表行相關,則需要建立 FOREIGN KEY 關系。 recipes表將需要一個id列,而ingredients表將需要一個像recipe_id這樣的列來存儲相應的食譜id 假設您的 html 表單已經知道所引用的配方,您應該在您的下方的行中包含<input type="hidden" name="recipe" value="<?php echo $recipeId; ?>">字段<form>標簽。 然后在保存數據時,您必須將$_POST['recipe']值與每個成分行一起保存。 然后,您將更好地使用“關系數據庫”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM