user1386320
user1386320

Reputation:

PHP unlink doesn't work

I have a multi-delete feature in one of my CMS solutions, and I have following code:

public function actionDelete() {
    if(Yii::app()->request->isPostRequest) {
        if(isseT($_POST['submit'])) {
            if(isset($_POST['delete']) && (sizeof($_POST['delete']))) {
                foreach($_POST['delete'] as $i => $items) {
                    $model[$i] = Pages::model()->findByPk((int)$items);

                    if(!is_null($model[$i])) {
                        $image[$i] = $model[$i]->image;

                        if($model[$i]->delete()) {
                            if(!unlink($image[$i])) {
                                die('Unable to delete Page Image.');
                            }
                        }
                    }
                }
            }
        }
    }

    $this->redirect('/admin/pages');
}

This is the action of a Yii controller, and on EVERY page there is a value filled in the "image" field/column.

After I invoke this action with post data, it acctually deletes the records from the database table, but it does not remove the pictures and images from the file system, and the script never comes up to this point: die('Unable to delete Page Image.');

Is it possible that PHP strips and ignores the unlink function, mostly on production / live servers?

Upvotes: 1

Views: 2612

Answers (2)

Wolfman Joe
Wolfman Joe

Reputation: 799

1: My first suggestion would be to test the $model[$i]->image value, to make sure it's outputting what you want it to output. Then, do an output of $image[$i] RIGHT before you try to unlink it. Make sure you're not trying to, say, delete a file which does not exist (which will always be a success.) Test the existence of the file before trying to delete it. I suspect this as a very likely case. Perhaps $model[$i]->image is saving the image path in terms of web access, and not as a file system?

2: I would highly recommend reversing the order of your deletions.

Right now, the database row is deleted first, then the image. If the delete process fails halfway through, then you've lost your link to the image that needs deleting.

If you do this instead:

if(!unlink($image[$i])) {
    if($model[$i]->delete()) {
        die('Unable to delete Page Image.');
    }
}

This allows you to only delete the database entry if the image is successfully deleted, which should help prevent unattached images from floating around your file system. If the delete process fails, you still have all the info needed to try deleting it again.

Upvotes: 1

Mike B
Mike B

Reputation: 32155

Is it possible that PHP strips and ignores the unlink function, mostly on production / live servers?

No, absolutely not (unless they've disabled that function but that should throw an error). It's either a logic error, permissions error, or pathing error.

Upvotes: 4

Related Questions