SQL::PDO удалить путь к изображению из БД, если рецепт удален

Я работаю в книге рецептов с SQL и PDO. В моей таблице «рецепты» есть столбец для «id», «name», «attachment_id»; Столбец 'attachment_id' является внешним ключом.

В таблице «вложения» есть столбцы «id», «attachment_path».

На данный момент, если я удаляю рецепт, изображение, путь к которому хранится в таблице «вложения», остается там. Чего я хочу добиться, так это того, что если я удалю рецепт, то «вложение», которое к нему принадлежит, также должно быть удалено. Я провел некоторое исследование и понял, что мне нужно создать триггер, но он продолжает показывать, что это неправильно, и я не могу понять, как это работает... или что делать с "разделителем". ...

Итак.... приступим:

functions.php:

 function delete_recipe($recipe_id = ':recipe_id', $attachment_id = ':attachment_id') {
              include 'db_connection.php';
        try {
            $sql = "DELETE FROM recipes ";
            $sql .= "WHERE id =:recipe_id ";
            $sql .= "LIMIT 1";

            $results = $conn->prepare($sql);
            $results->bindParam(':recipe_id', $recipe_id, PDO::PARAM_INT);

        if($results->execute()) {
          echo '1 row has been removed';  
          // if the recipe gets deleted, then delete its attachment
          delete_attachment($attachment_id);

        }

        $conn = null;

        } catch(PDOException $e) {
            echo 'Error: ' . $e->getMessage() . '<br />';
            return false;
        }

        return true;  
    }

function delete_attachment($attachment_id = ':attachment_id') {
       include 'db_connection.php';
    try {
        $sql = 'DELIMITER $$';
        $sql = 'CREATE TRIGGER image_before_delete_recipe';
        $sql .= ' AFTER DELETE ON `recipes`;
        $sql .= ' FOR EACH ROW BEGIN';
        $sql .= ' IF NEW.deleted THEN ';  

        $sql .= "DELETE FROM attachments ";
        $sql .= "WHERE id =:attachment_id ";
        $sql .= "LIMIT 1"; 

        $sql .= 'DELIMITER $$';

        $results = $conn->prepare($sql);
        $results->bindParam(':attachment_id', $attachment_id, PDO::PARAM_INT);

    if($results->execute()) {
      echo '1 row has been removed';  
    }

    $conn = null;

    } catch(PDOException $e) {
        echo 'Error: ' . $e->getMessage() . '<br />';
        return false;
    }

    return true;
}

Я знаю, что delete_attachment не имеет никакого смысла..... Я буквально не могу понять, как работает этот триггер и/или как мне его построить..... это обычный запрос на "удалить"?

Способ загрузки изображения:

  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
         $attach_id = filter_input(INPUT_POST, 'attach_id', FILTER_SANITIZE_NUMBER_INT);

       $folder="images/";
       $file = $_FILES['photo']['tmp_name'];
       $file_to_upload = $folder . basename($_FILES['photo']['name']);

       if(move_uploaded_file($file, $file_to_upload)) {
           echo "File is valid, and was successfully uploaded.\n";


       if($attach_id = add_image($file_to_upload)) {
           if(add_recipe($name, $attach_id)) {

               header('Location: index.php');
            exit;
          } else {
               $error_message = "Could not add recipe";
          } 
       } else {
               $error_message = "Could not add image";
          } 

       } else {
           echo 'Upload failure';
           print_r($_FILES);
       }  
    }

    include 'includes/header.php';?>
        <div class="col-container">
          <h1>Add a recipe</h1>
          <?php
          if (isset($error_message)) {
              echo '<p class="message">' . $error_message . '</p>';
          }
          ?>
          <form method="POST" action="recipe.php" enctype="multipart/form-data">   
            <div>
              <label for="name" class="required">Name</label>
              <input name="name" type="text" value="" />
            </div> 
            <div>  
        <input name="attach_id" type="text" value="" class="hidden" />  
            <label for="file">Filename:</label>
            <input type="file" name="photo" id="photo"><br>
            </div>
            <button class="submit" type="submit" name="submit">Submit</button>
          </form>
        </div>  
    <?php include 'includes/footer.php'; 

Я знаю, что это очень грязно и неправильно, я должен проверить, что данные поступают правильно, пустых полей нет..... но для начала я предпочитаю работать над функциональностью... Кто-нибудь может сказать мне, должен ли я обязательно сделать это с одним из этих триггеров, и если да.... как мне начать????

Спасибо


person eve_mf    schedule 14.11.2016    source источник
comment
$attachment_id равно :attachment_id Что вы ожидаете найти с таким значением?   -  person u_mulder    schedule 14.11.2016
comment
Может быть, я что-то здесь упускаю, но если вы знаете идентификатор вложения, входящего в удаление рецепта, нельзя ли просто запустить оба удаления одно за другим? Или, если вам нужно получить идентификатор вложения для удаления из рецепта, который вы удаляете, запустите запрос, чтобы получить идентификатор вложения, присвоить значение переменной, удалить запись рецепта, а затем удалить запись вложения.   -  person SGR    schedule 14.11.2016
comment
ну, то, что я хочу, это способ отправить это значение, значение для attachment_id из книги рецептов, когда рецепт удален... :S   -  person eve_mf    schedule 14.11.2016
comment
Триггер пишется и ХРАНИТСЯ в вашей базе данных так же, как и процедура. Он автоматически активируется самим MYSQL (а не вашим кодом), когда вы завершаете любое событие, на котором оно основано, т.е. удаляете строку в таблице xxx. Таким образом, вы создаете триггер один раз, и определенно не после того, как вы завершили действие, которое должно запустить триггер.   -  person RiggsFolly    schedule 14.11.2016
comment
Ага, SGR я понимаю, и это то, что я пытался сделать сначала, прежде чем я прочитал о триггерах и мой разум решил, что я должен сделать это с этим. Проблема в том, должен ли я сделать еще один запрос только для того, чтобы получить attachment_id до того, как рецепт будет удален?   -  person eve_mf    schedule 14.11.2016
comment
создать триггер в базе данных после удаления рецептов и заменить WHERE id =:attachment_id на WHERE id = OLD.ID. ВНИМАНИЕ, что этот id должен быть recipe_id, если в вашей структуре они не совпадают   -  person Vahe Shadunts    schedule 14.11.2016
comment
Тогда RiggsFolly, должен ли я использовать триггер, чтобы удалить вложение рецепта? или вместо этого удалить строку рецепта, а затем удалить вложение?   -  person eve_mf    schedule 14.11.2016
comment
Кроме того, вам нужно будет просмотреть строку attachment, прежде чем она будет удалена, чтобы вы могли удалить изображение из папки, в которой хранятся изображения.   -  person RiggsFolly    schedule 14.11.2016
comment
ааааа! спасибо SGR, попробую так, не подумал об этом! :D   -  person eve_mf    schedule 14.11.2016
comment
Если вы собираетесь использовать метод @SGR, и я согласен, это было бы хорошей идеей. Помните, что вы захотите запустить эти 2 запроса в транзакции, чтобы вы никогда не удалили одну строку, не удалив обе!!!   -  person RiggsFolly    schedule 14.11.2016
comment
Как вы можете узнать из связанного ответа, для реализации автоматического удаления вы должны использовать не триггер, а внешний ключ. который работает точно так же, как вы описали;   -  person Your Common Sense    schedule 14.11.2016
comment
Извините, но я не понимаю.... На данный момент attachment_id является внешним ключом таблицы recipes. Я видел, как кто-то поставил этот вопрос как дубликат, но я не вижу, где мой вопрос имеет какое-то отношение к вопросу о внешнем ключе MySQL при удалении .... Я теряюсь еще больше, чем когда я начал: s КОГДА я должен делать это с триггером тогда?   -  person eve_mf    schedule 14.11.2016