When delete image from mysql to delete also from folder

Hi,
I trying to make it when I delete image(row) from mysql to delete it also from folder. In mysql I store id, name of image, path of image… and image I store in folder.
So far I delete image successfully from DB but not from folder. Here is what I have so far. This is delete.php. In image_delete.php I just show all images from DB with button delete…

if (isset($_GET['id']) && is_numeric($_GET['id']))
{
    // get the 'id' variable from the URL
    $id = $_GET['id'];
    $name = "SELECT name FROM images WHERE id=$id";
    $name=mysql_fetch_assoc($name);
    $name=$name['name'];

    if ($stmt = $con->prepare("DELETE FROM images WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param("i",$id);
        unlink("../upload/" . $name);

        $stmt->execute();
        $stmt->close();
    }

    else
    {
        echo "ERROR: could not prepare SQL statement.";
    }
    $con->close();

    // redirect user after delete is successful
    header("Location: images_delete.php");
}

Is there a permissions problem with deleting files? Or is there an issue with the real path compared to the virtual path of the image? What does unlink() return? What is the exact content of the name field?

There is no problems with permissions. Real path is C:\wamp\www\upload\ … and content pf ‘name’ is for example ‘e3727a4c6dd6b8a7bba0069f8ca01144.jpg’

I’ve never tried this myself (mainly here to learn) but this stands out:


$name = "SELECT name FROM images WHERE id=$id";
$name=mysql_fetch_assoc($name);
$name=$name['name'];

Is it possible something is getting confused here by re-using $name? I’m not sure how this stuff works internally, when you say that’s what the name field contains, have you tried just displaying the contents of $name before you call unlink? And does unlink() return true or false?

I have show.php where I display all images from DB and delete.php where I delete some image when I press ‘delete’. When I check with var_dump($name); in show.php is NULL but I create $name in delete.php not in show.php
How to check if unlink() return true or false?

EDIT:
Here is what I get:

Warning: mysql_fetch_assoc() expects parameter 1 to be resource, string given
null
Warning: unlink(C:/wamp/www/upload/): Permission denied

So apparently there is also permission problem. But also something else
I tought there is no permission problem because if I try directly like unlink(‘C:\wamp\www\upload\image_name.jpg’); I’m able to delete it…

Ok, I fixed the permission issue but now I get strange result…

resource(6, mysql result)
Warning: unlink(C:/wamp/www/upload/Resource id #6): No such file or directory

I don’t know what is this and from where it come -> Resource id #6
Here is what i made

if (isset($_GET['id']) && is_numeric($_GET['id']))
{

    $id = $_GET['id'];
    $name = "SELECT * FROM images WHERE id=$id" or die(mysql_error());
    $name1=mysql_query($name);

    //print_r($name1);
    if ($stmt = $con->prepare("DELETE FROM images WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param("i",$id);
        $folder = 'C:\\wamp\\www\\upload';
        chown($folder,465);

        var_dump($name1);
        unlink($_SERVER['DOCUMENT_ROOT'] . "/upload/$name1");

        $stmt->execute();
        $stmt->close();
    }

    else
    {
        echo "ERROR: could not prepare SQL statement.";
    }
    $con->close();

Ah, but now you’ve missed out the mysql_fetch_assoc, so your $name1 variable is pointing to the query results, not a variable. So


$res = mysql_query($name);
$row = mysql_fetch_assoc($res);
$name1 = $row['name'];

Or something like that. And as I look at it, in the first one, you didn’t have the mysql_query statement, so that probably wouldn’t have helped.

I’m surprised the second sql to delete the image record from the database works, that bind_param() doesn’t look right to me, though it’s not the first time I’ve been caught out by an alternate method of operation.

Also someone will point out not to use mysql_ calls any more - you seem to use PDO in some parts but old calls in the other. Best to change while you don’t have so much code to change.


if (unlink(filename)) {
  // do things if it worked OK
}
else {
  // do things if it didn't
}

So now is working

$id = $_GET['id'];
    $name = "SELECT * FROM images WHERE id=$id" or die(mysql_error());
    $res = mysql_query($name);
    $row = mysql_fetch_assoc($res);
    $name1 = $row['name'];
    print_r($name1);
    if ($stmt = $con->prepare("DELETE FROM images WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param("i",$id);
        $folder = 'C:\\wamp\\www\\upload';
        chown($folder,777);

        var_dump($name1);
        unlink($_SERVER['DOCUMENT_ROOT'] . "/upload/$name1");

        $stmt->execute();
        $stmt->close();
    }

and delete image from DB and from folder
Here is what I get from print_r and var_dump

0d5bd560f37a38afc8b40cc99abb8c3e.jpg
string '0d5bd560f37a38afc8b40cc99abb8c3e.jpg' (length=36)

Yes, I know about mysql_* and I’ll change it. Just needed to work first.

What about bind->param()? Is working good?

I thought it should either be:


$stmt = $con->prepare("delete from image where id = :id");
$stmt->bind_param(':id', $id);

or


$stmt = $con->prepare("delete from image where id = ?");
$stmt->bind_param(1, $id);

But I’ve only tried the first way, so if it’s working it must just be one of the many other ways of doing the same. I know you can pass arrays as well.

I’ve tryed both but doesn’t work. When I press ‘Delete’ button just reload the page…
Also tryed this and also didn’t work.

$stmt = $con->prepare("DELETE FROM images WHERE id = :id LIMIT 1")
$stmt->bind_param(":id",$id);

Ah, like I said - my mistake. My way is using PDO, which is actually bindParam(), not bind_param(). You’re using mysqli, so that’s probably the difference - I haven’t used that.

So is it working now, ignoring my bind_param() confusion?

Yes, everything is working perfectly! Thanks for help!