Добрый день! Не могу разобраться с удалением из БД через цикл. Создание динамически добавленных элементов работает, также работает редактирование, а вот с удалением проблема edit_test.php Код (Text): <div class="card-body questions"> <?php $i = 1; ?> <?php foreach($get_questions as $question) { ?> <div class="callout callout-success" style="margin:30px 0;"> <div class="form-group question"> <label>Название</label> <input type="text" name="question[<?php echo $i; ?>][q_title]" class="form-control" value="<?php echo $question['title']; ?>" /> </div> <div class="form-group"> <label>Описание</label> <textarea id="editorquestion<?php echo $i; ?>" name="question[<?php echo $i; ?>][q_description]" class="form-control"><?php echo $question['description']; ?></textarea> </div> <div class="form-group"> <label>Правильный ответ</label> <input type="text" name="question[<?php echo $i; ?>][answer]" class="form-control" value="<?php echo $question['answer']; ?>" /> </div> <div class="form-group"> <button type="" name="question[<?php echo $i; ?>][delete]" class="btn btn-danger del-question">Удалить</button> </div> <input type="hidden" name="question[<?php echo $i; ?>][question_id]" value="<?php echo $question['question_id']; ?>" /> </div> <?php $i++; ?> <?php } ?> </div> edit_test_model.php Код (Text): function edit_test() { global $connection; $data = escape_data(); $query = "UPDATE tests SET title = '{$data['title']}', parent = '{$data['parent']}', meta_title = '{$data['meta_title']}', meta_description = '{$data['meta_description']}', meta_keywords = '{$data['meta_keywords']}', description = '{$data['description']}' WHERE test_id = {$data['test_id']}"; $res = mysqli_query($connection, $query); if(mysqli_affected_rows($connection) > 0) { $_SESSION['res']['ok'] = 'Данные обновлены!'; } else { $_SESSION['res']['error'] = 'Ошибка редактирования! Возможно вы ничего не меняли.'; } if(isset($_POST['question'])) { foreach ($_POST['question'] as $item) { if(isset($item['question_id'])) { $query = "UPDATE questions SET title = '{$item['q_title']}', description = '{$item['q_description']}', answer = '{$item['answer']}' WHERE question_id = '{$item['question_id']}'"; $res = mysqli_query($connection, $query); } else { $q_parent = $data['test_id']; $q_title = $item['q_title']; $q_description = $item['q_description']; $answer = $item['answer']; $query = "INSERT INTO questions (title, parent, description, answer) VALUES('$q_title', '$q_parent', '$q_description', '$answer')"; $res = mysqli_query($connection, $query); } if(isset($item['delete'])) { $query = "DELETE FROM questions WHERE question_id = '{$item['question_id']}'"; $res = mysqli_query($connection, $query); if(mysqli_affected_rows($connection) > 0) { return true; } else { return false; } } } } if(mysqli_affected_rows($connection) > 0) { $_SESSION['res']['ok'] = 'Данные обновлены!'; } else { $_SESSION['res']['error'] = 'Ошибка редактирования! Возможно вы ничего не меняли.'; } }
Удаление - как и любые другие запросы к БД в цикле - страшное зло. По вашему невнятному коду даже не хочется разбираться что там и как, но в целом - в цикле готовите только список id для удаления, удаляете одним запросом с условием IN (1,2,3,4,4,) который вы ранее сформировали в цикле, аналогично с вставкой
С чего он невнятный? Одним запросом по моему это днище, пример: админ удалил 1 элемент не нажимая кнопку сохранить, но передумал, так как ошибся и нажал не на тот элемент. Одумавшись, он просто нажал отменить и все настройки остались в целости и сохранности. По вашему, он нажал удалить и до свидания
@genych - используй классы вместо id. - $i = 1 вообще ненужно - максимально дели php код от html так код красивее смотрится правда? edit_test.php PHP: <div class="card-body questions"> <?php foreach($get_questions as $question) : $title = $question['title']; $descr = $question['description']; $answer = $question['answer']; $id = $question['question_id']; ?> <div class="callout callout-success" style="margin:30px 0;"> <div class="form-group question"> <label>Название</label> <input type="text" name="question[][q_title]" class="form-control" value="<?=$title;?>" /> </div> <div class="form-group"> <label>Описание</label> <textarea class="editorquestion" name="question[][q_description]" class="form-control"><?=$descr;?></textarea> </div> <div class="form-group"> <label>Правильный ответ</label> <input type="text" name="question[][answer]" class="form-control" value="<?=$answer?>" /> </div> <div class="form-group"> <button type="" name="question[][delete]" class="btn btn-danger del-question">Удалить</button> </div> <input type="hidden" name="question[][question_id]" value="<?=$id;?>" /> </div> <?php endforeach; ?> </div>
например потому-что глобальные - зло, еще не уверен что там за escape_data саморощенный... в целом вы не поняли что я сказал - делать запросы внутри цикла - плохо, готовьте данные в цикле - пожалуйста. а запросы - на основе этих данных или все сразу, или большими кусками
escape_data Код (Text): function escape_data($type = 'post') { global $connection; $data = []; if($type = 'post') { $data = $_POST; } elseif ($type == 'get') { $data = $_GET; } foreach ($data as $k => $v) { $data[$k] = mysqli_real_escape_string($connection, $v); } return $data; }
вот про это почитай, https://www.php.net/manual/ru/pdo.prepared-statements.php в твоем цикле будет $stmt->bindParam а выполнение sql запроса после цикла
типа в других случаях (вставка, обновление, удаление) - mysqli_real_escape_string необязательно? ну-ну ))))
Хорошо, что твоё мнение мало кого интересует. Ты можешь читать книги про паттерны, бест практикс и плыть в лодке. А можешь до посинения иметь своё собственное мнение и курить на обочине жизни.
У тебя там какой-то непонятный пример, слабо связанный с тем, о чем была речь. Для удаления вешай форму подтверждения на каждую кнопку или используй чекбоксы и общую кнопку удаления (в послед. случае можно не подтверждать). Что касается запросов, тебе просто говорят не делать множество запросов с условием `id`='$id', а сделать вместо них один с условием `id` IN($id_list). --- Добавлено --- @ADSoft, да норм. для соединения использовать глобальную переменную. --- Добавлено --- @genych, редактирование в смысле сохранения предполагает «перелопачивание» больших объемов данных. Тут лучше не тратить время на экранирование, а использовать подготовленные запросы. При удалении можно и экранировать идентификаторы. --- Добавлено --- ...или даже фильтровать, особенно если они числовые. --- Добавлено --- P.S. Идентификатор при сохранении можно и экранировать. Я писал про «основные» поля.
Стоит только посмотреть в код и начинаешь понимать, почему ТС так противится удалению одним запросом. Там в цикле происходит не только удаление, но и редактирование! @genych, не делайте так! Если нужно множественное редактирование, используйте AJAX и выполняйте сохранение отдельными записями или даже полями.