[英]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>
您不應該將表單字段重復為列表name0
, name1
.. 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,使用字段屬性,例如: title
、 placeholder
、 pattern
、 minlength
、 maxlength
、 required
等,以及可能的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_date
或created_on
或類似名稱,以便該值對您的腳本/項目的未來讀者提供更多信息。ingredients
表的架構,將insert_date
的 DEFAULT 值設置為 CURRENT_DATE。 這樣做時,您永遠不需要將此列寫入您的 INSERT 查詢——當您不為該列傳遞值時,數據庫將自動使用當前日期。id
列,則應添加一個並將其設為 PRIMARY KEY。 這是一種非常基本的技術,可以改善未來與表的交互,並且當您發現有人向表中提交了重復name
時,可以消除可能的混淆。至於處理您提交的數據,只需幾個簡單的步驟:
迭代$_POST
數組並隔離要插入數據庫的每一行數據。
隔離后,您需要在執行查詢之前驗證並選擇性地清理每一行,以便您永遠不會在表中存儲“壞數據”。
您正在使用mysqli
,這很好——您不需要切換到 pdo 來編寫安全/穩定的代碼。 4 您只需生成一次准備好的語句並將變量綁定到占位符一次。 只有語句的(條件)執行需要在循環內。 (其他一些例子: 1 , 2 , 3 )
但是,我建議您從 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>"; }
一些總體建議:
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.