问题描述
我只想使用一个函数插入所有值,并且我不想多次重写相同的代码,但是我遇到的问题是该函数仅插入第一个值(我检查了输入名称,并且设置正确)
$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]
另外,最好使用PHP生成HTML,以免违反DRY rule,您将意识到将来需要使用带有重复字段的表单来编辑表单:
<!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注入的数据等。 当重复执行同一条语句时,它们的执行速度也更快。
注意:代码未经测试,可能需要进行一些语法检查和其他更正
{ propA: number; propB: null } | { propA: null; propB: string }
,
首先,请精心制作html表单,使其适合特定目的并且不违反html文档标准。
-
您应该在循环内生成输入字段的行。
-
您应该使用数组语法声明每个字段的
name
属性,以便将行数据提交到分组的子数组中-这将使后续处理变得更加容易。只需使用[]
尾随字段名,就可以避免不必要的php语法使文件混乱。 -
您不得在单个文档中重复
id
属性。您可以在id
字符串的末尾附加一个计数器,但是很有可能根本不需要id
声明-我将省略它们。 -
将
<option>
的文本复制为其value
的值有零好处。只需忽略该属性声明。 -
使用测量单位白名单,这样您就不必一遍又一遍地写出每个
<option>
标签。这样可以提高脚本的可维护性。 -
对于改进的UX,请使用字段属性,例如:
title
,placeholder
,pattern
,minlength
,maxlength
,{{1} }等,并可能使用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
的DEFAULT值设置为CURRENT_DATE。这样,您将不需要将此列写入INSERT查询中-当您不为该列传递值时,数据库将自动使用当前日期。 - 如果该表没有自动增加
insert_date
列,则应添加一个并将其设置为PRIMARY KEY。这是一项非常基本的技术,可以改善以后与表格的互动,当您发现有人向表格中提交了id
的副本时,它将消除可能的混淆。
对于处理您提交的数据,只需遵循几个简单步骤:
-
迭代
name
数组并隔离要插入数据库的每一行数据。 -
一旦隔离,您需要在执行查询之前验证并可选地清理每一行,这样您就永远不会在表中存储“不良数据”。
-
您正在使用
$_POST
,这很好-您不需要 切换到pdo来编写安全/稳定的代码。 4您只需要生成一次准备好的语句,并将变量绑定到占位符一次即可。只有(条件)语句的执行需要在循环内。 (其他一些示例:1,2,3) -
但是,我建议您从mysqli的过程语法切换到其面向对象的语法。它更加简洁,我觉得它更易于阅读。
mysqli
一些总体建议:
- 避免将法语和英语混在一起。如果要使用法语变量名称,请使用所有法语变量。就是说,我已经阅读了以英语为母语的人和作为第二语言的英语开发人员的建议,他们指出,您应始终在代码中使用所有英语-这是一场辩论,我现在不会对此进行讨论。
- When to use htmlspecialchars() function?您会注意到,我从未在答案中调用此函数。这是因为我们绝不会在屏幕上打印任何用户输入。验证?是。消毒吗?当然。 HTML编码?不;不是这里,不是现在。
- 如果这些成分行旨在与特定的
// create a mysqli connection object e.g. $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','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>"; }
表行相关,那么您将需要建立FOREIGN KEY关系。recipe
表将需要一个recipes
列,而id
表将需要一个诸如ingredients
的列,用于存储相应的配方recipe_id
。假设您的html表单已经知道要引用哪个配方,则应在id
标记下的行中包含一个<input type="hidden" name="recipe" value="<?php echo $recipeId; ?>">
字段。然后,在保存数据时,必须在每个配料行中保存<form>
值。然后,您将更好地使用“关系数据库”。