Delete comma separated records

Asked

Viewed 48 times

0

I am uploading several images and storing them in the bank, so far it is perfect. The records are recorded, separated by comma in the field materialDocumento on the table tb_material. The problem is that I am not able to delete a specific image that is selected when necessary. Could you help me?

The files are recorded in the database as follows:

498818_03c4414ce0324292a51e63009f513a82_mv2.jpg, 64223640_2226772990741441_1192728863528976384_o.jpg, 64254162_1912126265586260_4480819099357675520_o.jpg, 25044125149117.jpg

php.

<a href="material-edita.php?edita_material_ID=<?php echo $_GET['edita_material_ID']; ?>&imagem_material=<?php echo $img; ?>"><button type="submit" class="btn btn-large btn-danger" name="btn-deletar-imagem"><i class="fa fa-trash"></i> &nbsp; Excluir Imagem Material</button></a>

<?php
  if (isset($_GET['edita_material_ID'])) {
      $materialID = $_GET['edita_material_ID'];
      extract($classeMaterial->getID($materialID));

      $mDocumento = $_GET['imagem_material'];

  if ($classeMaterial->deletarArqImg($materialID, $mDocumento)) {
    var_dump($mDocumento);
  }
}
?>

class.classe_material.php

<?php
    public function deletarArqImg($materialID, $mDocumento) 
    {
        try {
            $stmt = $this->db->prepare("DELETE FROM tbl_material WHERE materialID = :materialID AND materialDocumento = :mDocumento");
            $stmt->bindparam(":mDocumento", $mDocumento);
            $stmt->bindparam(":materialID", $materialID);
            $stmt->execute();
            return true;

            } catch (PDOException $e) {
            echo $e->getMessage();
            return false;
        }
    }
?>
  • 1

    If you just want to delete a specific image, it doesn’t make much sense to give DELETE in the entire record. It would not be better to make a UPDATE removing the image from the list?

  • 1

    The simplest would be to record each image with an id, now being together you will have to retrieve the record, and separate with an explode, which will generate an array and then find the respective index... That is, rethink the way to save the images...

  • Yes Anderson, I agree. But when I give UPDATE, it deletes all the records and adds the record I wanted to delete. I believe the explosion could solve as Magichat commented. Could give me an orientation of how to do it?

  • 1

    Fabio, the exploding solution will give you a lot more headache than remodeling this section in your database. If you’re messing with this, redo it, waste a little more time. Create an image-only table, each image with an id, and associate with the material id.

  • Precisely, since you are using a relational bank, you have no reason to benefit from it to solve the problem.

1 answer

1


Since you were storing a "collection" of string values you need to understand what you are doing.

All your documents related to a particular material are saved as a single value (string). So your database does not understand that there are several related documents because this structure was not carried out. But as you know that there are several relationships the ideal is to follow the suggestion of @Andersoncarloswoss and carry out a update in string.


First, you need to get the record to be updated (If you don’t have a method for this):

public function find($id)
{
    $stmt = $this->db->prepare("SELECT * FROM tbl_materia WHERE materialID = ?");
    $stmt->execute(array($id));
    $material = $stmt->fetchAll();
    return $material[0];
}

After obtaining the registration by id, it is necessary to check whether the document to be deleted exists to then carry out the update in place of delete.

public function deletarArqImg($materialID, $mDocumento) 
{
    $material = $this->find($materialID);

    //Utilizar o array_map para aplicar a função trim (remover os espaços vazios do lado direito e esquerdo) em cada valor do array
    $documentos = array_map('trim', explode(',', $material['materialDocumento']));

    $key = array_search($mDocumento, $documentos); //Verificar se existe o documento a ser "excluído"
    if ($key !== false) {
        unset($documentos[$key]); //Removendo o documento do array de documentos
        $newDocumentos = implode(',', $documentos);

        try {
            $update = $this->db->prepare("UPDATE tbl_material SET materialDocumento = :newDocumentos WHERE materialID = :materialID");
            $update->bindParam(":newDocumentos", $newDocumentos);
            $update->bindParam(":materialID", $materialID);    
            return $update->execute(); //Retorna TRUE para sucesso ou FALSE para falha
        } catch (PDOException $e) {
            echo $e->getMessage();
            return false;
        }
    }
}
  • It’s not safe to do if ($key) to validate the return of array_search, because the value sought may be the first of the array and return the index 0, not entering the if. The ideal is to make if ($key !== false) given that the return is false when value is not found. Or using Yoda conditions: if (false !== $key).

  • Thanks @Andersoncarloswoss for the remark, now I never forget it xD

  • The big problem is how to inform the correct position to be replaced, how will the application identify the record to be deleted? It can be index 0, hour index 2 and so on... Each image has to have its own identifier.

  • The correct one would be this way even, obdeceecendo the structure one to Many But for the case he reported, there’s not much to do. It can do the solution I posted or restructure that part in the database as you had suggested.

  • I am showing the following error: Parse error: syntax error, Unexpected '$material' (T_VARIABLE), expecting ',' or ')' in classes classe_material class.classe_material.php on line 158

  • @Fabio, updated the response with the correction. The instruction explode need two parameters separated by comma, was being passed the two parameters but without separation.

  • 1

    Perfect Victor. Got it, worked correctly, thank you very much. Thank you so much for your help. And I agree with colleagues, the best and easiest procedure would be to create a separate table. But the problem is to change the whole structure of the project and add another JOIN in my QUERY S, which are already quite large by the amount of related tables I have. But your help was fantastic and I thank you all for your help.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.