За последние 24 часа нас посетили 22303 программиста и 1045 роботов. Сейчас ищут 593 программиста ...

Удаление из БД через цикл

Тема в разделе "PHP для новичков", создана пользователем genych, 3 фев 2020.

  1. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    Добрый день!
    Не могу разобраться с удалением из БД через цикл. Создание динамически добавленных элементов работает, также работает редактирование, а вот с удалением проблема

    edit_test.php
    Код (Text):
    1. <div class="card-body questions">
    2.     <?php $i = 1; ?>
    3.     <?php foreach($get_questions as $question) { ?>
    4.     <div class="callout callout-success" style="margin:30px 0;">
    5.         <div class="form-group question">
    6.             <label>Название</label>
    7.             <input type="text" name="question[<?php echo $i; ?>][q_title]" class="form-control" value="<?php echo $question['title']; ?>" />
    8.         </div>
    9.         <div class="form-group">
    10.             <label>Описание</label>
    11.             <textarea id="editorquestion<?php echo $i; ?>" name="question[<?php echo $i; ?>][q_description]" class="form-control"><?php echo $question['description']; ?></textarea>
    12.         </div>
    13.         <div class="form-group">
    14.             <label>Правильный ответ</label>
    15.             <input type="text" name="question[<?php echo $i; ?>][answer]" class="form-control" value="<?php echo $question['answer']; ?>" />
    16.         </div>
    17.         <div class="form-group">
    18.             <button type="" name="question[<?php echo $i; ?>][delete]" class="btn btn-danger del-question">Удалить</button>
    19.         </div>
    20.         <input type="hidden" name="question[<?php echo $i; ?>][question_id]" value="<?php echo $question['question_id']; ?>" />
    21.     </div>
    22.     <?php $i++; ?>
    23.     <?php } ?>
    24. </div>
    edit_test_model.php

    Код (Text):
    1. function edit_test() {
    2.     global $connection;
    3.     $data = escape_data();
    4.     $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']}";
    5.     $res = mysqli_query($connection, $query);
    6.     if(mysqli_affected_rows($connection) > 0) {
    7.         $_SESSION['res']['ok'] = 'Данные обновлены!';
    8.     } else {
    9.         $_SESSION['res']['error'] = 'Ошибка редактирования! Возможно вы ничего не меняли.';
    10.     }
    11.     if(isset($_POST['question'])) {
    12.         foreach ($_POST['question'] as $item) {
    13.             if(isset($item['question_id'])) {
    14.                 $query = "UPDATE questions SET title = '{$item['q_title']}', description = '{$item['q_description']}', answer = '{$item['answer']}' WHERE question_id = '{$item['question_id']}'";
    15.                 $res = mysqli_query($connection, $query);
    16.             } else {
    17.                 $q_parent = $data['test_id'];
    18.                 $q_title = $item['q_title'];
    19.                 $q_description = $item['q_description'];
    20.                 $answer = $item['answer'];
    21.                     $query = "INSERT INTO questions (title, parent, description, answer)
    22.                                 VALUES('$q_title', '$q_parent', '$q_description', '$answer')";
    23.                 $res = mysqli_query($connection, $query);
    24.             }
    25.             if(isset($item['delete'])) {
    26.                 $query = "DELETE FROM questions WHERE question_id = '{$item['question_id']}'";
    27.                 $res = mysqli_query($connection, $query);
    28.                 if(mysqli_affected_rows($connection) > 0) {
    29.                     return true;
    30.                 } else {
    31.                     return false;
    32.                 }
    33.             }
    34.         }
    35.     }
    36.     if(mysqli_affected_rows($connection) > 0) {
    37.         $_SESSION['res']['ok'] = 'Данные обновлены!';
    38.     } else {
    39.         $_SESSION['res']['error'] = 'Ошибка редактирования! Возможно вы ничего не меняли.';
    40.     }
    41. }
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.820
    Симпатии:
    736
    Адрес:
    Татарстан
    Удаление - как и любые другие запросы к БД в цикле - страшное зло.
    По вашему невнятному коду даже не хочется разбираться что там и как, но в целом
    - в цикле готовите только список id для удаления, удаляете одним запросом с условием IN (1,2,3,4,4,) который вы ранее сформировали в цикле, аналогично с вставкой
     
  3. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    С чего он невнятный? Одним запросом по моему это днище, пример: админ удалил 1 элемент не нажимая кнопку сохранить, но передумал, так как ошибся и нажал не на тот элемент. Одумавшись, он просто нажал отменить и все настройки остались в целости и сохранности. По вашему, он нажал удалить и до свидания
     
  4. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @genych
    - используй классы вместо id.
    - $i = 1 вообще ненужно
    - максимально дели php код от html

    так код красивее смотрится правда?

    edit_test.php
    PHP:
    1. <div class="card-body questions">
    2.  
    3.     <?php
    4.         foreach($get_questions as $question) :
    5.  
    6.             $title = $question['title'];
    7.             $descr = $question['description'];
    8.             $answer = $question['answer'];
    9.             $id = $question['question_id'];
    10.     ?>
    11.  
    12.     <div class="callout callout-success" style="margin:30px 0;">
    13.         <div class="form-group question">
    14.             <label>Название</label>
    15.             <input type="text" name="question[][q_title]" class="form-control" value="<?=$title;?>" />
    16.         </div>
    17.         <div class="form-group">
    18.             <label>Описание</label>
    19.             <textarea class="editorquestion" name="question[][q_description]" class="form-control"><?=$descr;?></textarea>
    20.         </div>
    21.         <div class="form-group">
    22.             <label>Правильный ответ</label>
    23.             <input type="text" name="question[][answer]" class="form-control" value="<?=$answer?>" />
    24.         </div>
    25.         <div class="form-group">
    26.             <button type="" name="question[][delete]" class="btn btn-danger del-question">Удалить</button>
    27.         </div>
    28.         <input type="hidden" name="question[][question_id]" value="<?=$id;?>" />
    29.     </div>
    30.  
    31.     <?php
    32.         endforeach;
    33.     ?>
    34.  
    35. </div>
     
  5. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.820
    Симпатии:
    736
    Адрес:
    Татарстан
    например потому-что
    глобальные - зло, еще не уверен что там за escape_data саморощенный...

    в целом вы не поняли что я сказал - делать запросы внутри цикла - плохо, готовьте данные в цикле - пожалуйста. а запросы - на основе этих данных или все сразу, или большими кусками
     
  6. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    escape_data
    Код (Text):
    1. function escape_data($type = 'post') {
    2.     global $connection;
    3.     $data = [];
    4.     if($type = 'post') {
    5.         $data = $_POST;
    6.     } elseif ($type == 'get') {
    7.         $data = $_GET;
    8.     }
    9.     foreach ($data as $k => $v) {
    10.         $data[$k] = mysqli_real_escape_string($connection, $v);
    11.     }
    12.     return $data;
    13. }
     
  7. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
  8. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.820
    Симпатии:
    736
    Адрес:
    Татарстан
    типа в других случаях (вставка, обновление, удаление) - mysqli_real_escape_string необязательно?
    ну-ну ))))
     
  9. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    Дружище, отвергаешь - предложил)))
     
  10. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Хорошо, что твоё мнение мало кого интересует. Ты можешь читать книги про паттерны, бест практикс и плыть в лодке. А можешь до посинения иметь своё собственное мнение и курить на обочине жизни.
     
  11. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    )))) ты о чем?
     
  12. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    О жизни))
    О том, что тебе говорят как нужно делать, а ты так не делаешь.
     
  13. genych

    genych Новичок

    С нами с:
    2 сен 2018
    Сообщения:
    42
    Симпатии:
    3
    пздц
    ты кто, блин??? Зашел мое мнение прочитать, обсудить, обосрать, ты дол**еб?
     
  14. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.790
    Симпатии:
    649
    У тебя там какой-то непонятный пример, слабо связанный с тем, о чем была речь. Для удаления вешай форму подтверждения на каждую кнопку или используй чекбоксы и общую кнопку удаления (в послед. случае можно не подтверждать). Что касается запросов, тебе просто говорят не делать множество запросов с условием `id`='$id', а сделать вместо них один с условием `id` IN($id_list).
    --- Добавлено ---
    @ADSoft, да норм. для соединения использовать глобальную переменную.
    --- Добавлено ---
    @genych, редактирование в смысле сохранения предполагает «перелопачивание» больших объемов данных. Тут лучше не тратить время на экранирование, а использовать подготовленные запросы. При удалении можно и экранировать идентификаторы.
    --- Добавлено ---
    ...или даже фильтровать, особенно если они числовые.
    --- Добавлено ---
    P.S. Идентификатор при сохранении можно и экранировать. Я писал про «основные» поля.
     
  15. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.790
    Симпатии:
    649
    Стоит только посмотреть в код и начинаешь понимать, почему ТС так противится удалению одним запросом. Там в цикле происходит не только удаление, но и редактирование!

    @genych, не делайте так! Если нужно множественное редактирование, используйте AJAX и выполняйте сохранение отдельными записями или даже полями.