-1

I try to delete multiple images from folder and also from database, deleting from database is working fine, problem is with deleting from folder I'm using explode function because I have store multiple images inside one column in database. It just won't delete images from folder.

    $query = "DELETE FROM table_gallery WHERE id = $deleteId";
    $result = mysqli_query($con, $query);

    while($row = mysqli_fetch_assoc($result)) {
            $temp = explode(',',$row['images'] );
            foreach($temp as $image){
                    $images[]="uploads/gallery/".trim( str_replace( array('[',']') ,"" ,$image ) );
            }
            foreach($images as $file) {
                    // Delete given images
                    unlink($images);
                }
        }
ADyson
  • 57,178
  • 14
  • 51
  • 63
GPA
  • 111
  • 2
  • 10
  • 3
    `won't` isn't an error message or a useful problem statement. Do some debugging and let us know the outcome if you don't understand what you find. Check for errors and warnings (switch them on in PHP if they're not enabled) and add some logging to trace what the code is doing. Stackoverflow isn't a free debugging service (and anyway we can't do any active debugging since we can't run your code). And since you didn't provide any examples of the data contained in `$images` we can't predict what the code will do either. – ADyson Mar 10 '21 at 11:56
  • P.S. Storing multiple values in a single field like that is bad practice and indicative of a flawed and de-normalised database design. Re-consider your schema design and create a second table to store each image record in a separate row, with a foreign key back to the gallery table. This will make it easier to run queries, extract the data, collect statistics etc. Study database relationships and normalisation if you are not familiar with the topic. – ADyson Mar 10 '21 at 12:00
  • P.P.S. Your DELETE query may be vulnerable to SQL injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. **Never** insert unsanitised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. – ADyson Mar 10 '21 at 12:00
  • First Select the rows and then delete as your are iterating over. – shahmanthan9 Mar 10 '21 at 12:00
  • Oh and a more obvious thing I've just noticed.... DELETE queries don't return results. So `$result` will not contain anything you can loop over. That's a pretty fundamental issue. SQL DELETE never returns rows, it just deletes things. You need to SELECT the row from the table _before_ you delete it, if you need to get information from it. Judging by that, plus your usage of multiple values in a field and the SQL injection issue, I think maybe you need to do some more basic study to improve your overall knowledge of fundamental SQL concepts. – ADyson Mar 10 '21 at 12:02
  • `$deleteId = '1 OR id > 1';` is a security risk for your SQL and an example of deleting all records on your table. You should use Prepared Statements. – Martin Mar 10 '21 at 12:15
  • 1
    P.S. Don't update your question to modify the code into the final working version. It makes all the comments and answers seem nonsensical, as they're commenting on an earlier version. Only edit the question to provide _more_ info, not overwrite earlier info. If the answer below helped you, you can just accept it. Nothing further is needed by way of explanation. So if you aren't expecting us to comment on these updates, and you're not providing any other information along with it, then please roll back any edits until your code is in the original state. – ADyson Mar 10 '21 at 14:00
  • As you took no action, I've taken it for you. The code is back to its original state and the question makes sense again. – ADyson Mar 10 '21 at 18:25

1 Answers1

3

You have a few issues going on here,

1) Variable Confusion

The most notable is this:

   foreach($images as $file) {
          // Delete given images
          unlink($images);
   }

You are opening the array of $images and then dealing with each element in the array as a string reference ($file), but your unlink() command is calling the array, and you can't do that.

Unlink requires you to give it a filepath string. Not an array.

Fix:

foreach($images as $file) {
          // Delete given images
          unlink($file);
   }

Better:

As an aside, if unlink($file); does not work, then you should check your filepath is correct. Remember the current PHP working directory is the directory the PHP script is in, so you should probably set your deleted image path to being the full server filepath such as:

 unlink($_SERVER['DOCUMENT_ROOT']. $file); 

To ensure you're certain of the file you're deleting.

foreach($images as $file) {
          // Delete given images
          // /serverfolder/accountfolder/public_html/uploads/gallery/imagename.jpg
          unlink($_SERVER['DOCUMENT_ROOT'].$file);
   }

2) Your Safety and Security:

Your variable $deleteId might be safe, but it might not. We can't tell from the code you show but you should be aware that if the $deleteId variable is, for example;

 $deleteId = '1 OR id > 1';
 // which generates:
 $query = "DELETE FROM table_gallery WHERE id = 1 OR id > 1";

This is a security risk for your SQL and will delete all records on your database table (and folder). You should use Prepared Statements to ensure this doesn't ever happen.

3) Logic Confusion

you have a reference call mysqli_fetch_assoc but the DELETE SQL command will not return a result set, instead if it is successful it will simply return true.

Returns false on failure. For successful queries which produce a result set, such as SELECT, SHOW, DESCRIBE or EXPLAIN, mysqli_query() will return a mysqli_result object. For other successful queries, mysqli_query() will return true.

You need to structure your code somewhat differently, loading the images column value BEFORE you delete the row.

So, to restructure your code:

    1. Check variables are safe.
    1. load images column values
    1. cycle through values and delete
    1. Once deletion is confirmed then DELETE SQL.

For example:

$query = "SELECT images FROM table_gallery WHERE id = ".(int)$deleteId;
$result = mysqli_query($con, $query);
$abort = false;

while($row = mysqli_fetch_assoc($result)) {
        $temp = explode(',',$row['images'] );
        foreach($temp as $image){
                $images[]="uploads/gallery/".trim( str_replace( array('[',']') ,"" ,$image ) );
        }
        foreach($images as $file) {
                // Delete given images
                if(!unlink($_SERVER['DOCUMENT_ROOT'].$file)){
                   // Delete failed so abort
                   $abort = true; 
                }
            }
       //
       if(!$abort){
           // all correct images on disk deleted ok so delete DB row
           if(mysqli_query($con, "DELETE FROM table_gallery WHERE id = ".(int)$deleteId)){
               // Yay deleted ok!
           }
       }
    }

Closing thought:

You need to learn to read your PHP error logs which will spell out all the above.

Martin
  • 22,212
  • 11
  • 70
  • 132