Поскольку вы вызываете array_combine()
, ваш цикл больше не передает индексы подмассива как $i
. Он передает subject_id
как $i
и grade_id
как $val
. Вы могли бы просто использовать $i
и $val
в качестве значений для вставки, а не пытаться повторно получить доступ к массивам $_POST
с помощью $i
.
Более чистые сценарии будут использовать идентификаторы в качестве жестко закодированных ключей элементов на каждом <select>
вместо передачи скрытого поля.
<?php
$options = [
5 => 'excellent',
4 => 'very good',
3 => 'good',
2 => 'ok',
1 => 'bad'
];
?>
<td><?= $unos[$row]["subject"]; ?></td>
<td><select class="form-control input-xs" name="grade[<?= $unos[$row]["id"]; ?>]" required>
<option disabled>Select grade</option>
<?php
foreach ($options as $opt_id => $opt_val) {
echo "<option value=\"{$opt_id}\">{$opt_val}</option>";
}
?>
</select>
</td>
Тогда вы можете просто получить доступ к ассоциативному представлению.
if (isset($_POST['grade'])) {
// use prepared statement and bind variables
foreach ($_POST['grade'] as $id => $val) {
// execute prepared statement with each iteration
}
}
В качестве альтернативы, вы можете создать один пакет результатов и сделать одну INSERT (я бы, вероятно, сделал это так).
Непроверенное предложение:
$data = [];
foreach ($_POST['grade'] as $subject_id => $grade_id) {
array_push($data, $subject_id, $grade_id); // restructure as indexed 1-dim array for unpacking
}
$num_of_inserts = sizeof($data);
$placeholders = array_fill(0, $num_of_inserts, '(?,?)');
$value_types = str_repeat('i', $num_of_inserts * 2); // i is because you are passing integer values
// execute single batch of inserts
$query = "INSERT INTO final_grade (subject_id,grade_id) VALUES " . implode(',', $placeholders);
$stmt = $conn->prepare($query);
$stmt->bind_param($value_types, ...$data);
$stmt->execute();
На самом деле есть несколько способов передачи данных из формы и несколько способов выполнения запроса INSERT. Я не буду писать все варианты - делайте что хотите ... но обязательно пишите стабильные / безопасные запросы.