Page 1 of 1

Problems with unlink()

Posted: Tue Nov 18, 2008 1:47 pm
by Hendeca
Hello,

I've been looking for a solution to this problem for a while now. I've tried many things, and nothing seems to help.

I have a photo upload form on my sister's website which takes an image, resizes it to both thumb size and a size that fits the site's display div, and then creates a database record for the photo based on a name and filename form. In addition, I have pages that list all of the photos in a particular database and allows for editing and deletion of the photos. I've been able to alter and delete database records, but I've still been unable to actually delete the file.

Here is the code, which is an alteration of the code for a deletion form from David Powers' PHP Solutions:

Code: Select all

<?php
include('includes/connection.lizzie.inc.php');
include('includes/corefuncs.php');
define (DELETE_DIR, '/home/owstopit/lizziewrightphotography.com/css/images/photos/wallsanddoors/');
//remove backslashes
nukeMagicQuotes();
//initialize flags
$OK = false;
$done = false;
//create database connection
$conn = dbConnect();
//get details of selected record
if (isset($_GET['photo_id']) && !$_POST) {
    //prepare SQL query
    $sql = 'SELECT photo_id, photo_name, file_name
            FROM wallsanddoors WHERE photo_id = ?';
    //initialize statement
    $stmt = $conn->stmt_init();
    if ($stmt->prepare($sql)) {
        //bind the query parameters
        $stmt->bind_param('i', $_GET['photo_id']);
        //bind the results to variables
        $stmt->bind_result($photo_id, $photo_name, $file_name);
        //execute the query and fetch the result
        $OK = $stmt->execute();
        $stmt->fetch();
        }
    }
// if confirm deletion button has been clicked, delete record
if (array_key_exists('delete', $_POST)) {
  $sql = 'DELETE FROM wallsanddoors WHERE photo_id = ?';
  $stmt = $conn->stmt_init();
  unlink(DELETE_DIR.$file_name);
  if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $_POST['photo_id']);
    $deleted = $stmt->execute();
    }
  }
// redirect the page if deletion is successful, cancel button clicked, or $_GET['article_id'] not defined
if ($deleted || array_key_exists('cancel_delete', $_POST) || !isset($_GET['photo_id']))  {
  header('Location: http://www.lizziewrightphotography.com/ ... doors.php');
  exit;
  }
//display error message if query fails
if (isset($stmt) && !$OK && !$done) {
    echo $stmt->error;
    }
?>
I left out the body of the page, which is just a readout of the database record and the confirm delete and cancel buttons.
I have tried changing directories to the photo directory then just directly unlinking the filename, but that hasn't worked. Maybe something's up with the $file_name variable? I also tried wrapping the unlink() function in a conditional statement and found that it always failed. Another strange thing is that the failed unlink() function doesn't throw an error... I read that it was supposed to? Anyone know what's up? Also tried changing file permissions for the photo directory (tried every possible combination). Help!

Thanks,
-Neal

Re: Problems with unlink()

Posted: Tue Nov 18, 2008 10:59 pm
by novice4eva
did you try to echo "$file_name" to check if it really contains anything at all ??

Re: Problems with unlink()

Posted: Tue Nov 18, 2008 11:29 pm
by Hendeca
Hey,

I just tried echoing $file_name and it looks like it's the correct filename with the extension.

However I got this error:

[function.unlink]: Is a directory in /home/owstopit/lizziewrightphotography.com/private/delete_photo_wallsanddoors.php on line 33

The directory it's referring to is the current page (the photo delete page). What does this mean? Does this mean that it's trying to find the file in the current directory? What's goin on?

Also, am I using the proper syntax for combining the DELETE_DIR constant and the $file_name variable? I currently have this:
unlink(DELETE_DIR.$file_name);

Thanks!

Re: Problems with unlink()

Posted: Wed Nov 19, 2008 2:22 am
by novice4eva
ahh right, the DELETE_DIR you have defined, the unlink function tries to access this file from your working folder. Lets say for the time being you are in http://www.yousite.com/content/delete.php, so now when we do unlink(DELETE_DIR.$file_name), it is trying to delete http://www.yoursite.com/content/home/ow ... myFile.php considering $file_name=myFile.php when the correct URL would be http://www.yoursite.com/home/owstopit/l ... myFile.php

OK since we have caught the problem, well the solution should be to prepend appropriate number of "../" to the DELETE_DIR.
Hope that solves it :)

Re: Problems with unlink()

Posted: Wed Nov 19, 2008 4:38 am
by Hendeca
Hmm, well I'm not sure that's the problem because:

1. I already tried a script in which I changed directories to the proper folder and referenced just the filename unsucessfully

2. I tried linking directly to the website's address as opposed to using /home/...etc. which still didn't work.

However I did realize that I was not getting an error message because the site was redirecting right after the unlink function and therefore giving no chance to see the error. I referenced the directory through it's http:// address directly and got this error:

Warning: unlink() [function.unlink]: http does not allow unlinking in /home/owstopit/lizziewrightphotography.com/private/delete_photo_wallsanddoors.php on line 36

I am currently talking to Dreamost about how to set up the directories and hopefully it will be fixed!

Thanks!

-Nealo

Re: Problems with unlink()

Posted: Wed Nov 19, 2008 4:46 am
by aceconcepts
I think what notice4eva was saying is reference the directory relative to where the function is being called i.e. using "../"

Re: Problems with unlink()

Posted: Wed Nov 19, 2008 4:58 am
by Hendeca
Oh, well doesn't the chdir() function change the directory relative the unlink() function if the unlink() function is called after the chdir() function? I tried that already and didn't get anything. However I can try it with the ../ method instead. Thanks for the help, I'll try it out!

-Neal

Re: Problems with unlink()

Posted: Wed Nov 19, 2008 5:09 am
by Hendeca
I tried the ../ way of changing directories but this threw the same error as the original error I posted. I am starting to feel pretty sure that it is the file permission setup, as I've been talking to Dreamhost Tech Support... I'll keep you posted

-Neal

Re: Problems with unlink()

Posted: Thu Dec 18, 2008 1:06 am
by Hendeca
Well after talking to Dreamhost, I was told that this function should be possible and even got someone to change all of the file permissions just in case I was doing it wrong. STILL WON'T WORK! Please, please, someone, shed some light on why this isn't working? I am going crazy! 8O

Re: Problems with unlink()

Posted: Thu Dec 18, 2008 8:20 pm
by novice4eva
OK let's start again by enabling the error which is to put these :

Code: Select all

 
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
 
The let us check the value of the $_SERVER['DOCUMENT_ROOT'], and then define DELETE_DIR with the $_SERVER['DOCUMENT_ROOT'] attached to it, just to make sure we are pointing at the right directory, which by the nature of errors seen are apparently not !!

And again lets see what unlink is returning, it must be returning false but then also,

Code: Select all

 
$file = DELETE_DIR.$file_name;
if(!unlink($file))
{
     echo '<hr>'.$file.'<hr>';
     echo '<hr>'.substr(sprintf('%o', fileperms($file)), -4).'<hr>';
 
}
 
So now we have got the file name and permission too. Lets see what happens

Re: Problems with unlink()

Posted: Fri Jan 02, 2009 5:39 pm
by Hendeca
Hey,

Thanks for the help! For some reason it wasn't able to retrieve the permissions. However, now I've discovered the majority of the problem. I tried moving the unlink to different places in the code, and found that if it's not in one of the conditional if statements, it works! I'm not sure why. Now the problem remains: how can I make sure that the files are only deleted after the confirm delete button has been pushed? Why isn't it deleting when the unlink() function is nested in an if statement? I'll show you some examples of what I'm talking about:


This works:

Code: Select all

if (isset($_GET['photo_id']) && !$_POST) {
    //prepare SQL query
    $sql = 'SELECT photo_id, photo_name, file_name, thumb_name
            FROM wallsanddoors WHERE photo_id = ?';
    //initialize statement
    $stmt = $conn->stmt_init();
    if ($stmt->prepare($sql)) {
        //bind the query parameters
        $stmt->bind_param('i', $_GET['photo_id']);
        //bind the results to variables
        $stmt->bind_result($photo_id, $photo_name, $file_name, $thumb_name);
        //execute the query and fetch the result
        $OK = $stmt->execute();
        $stmt->fetch();
        }
    }
   [color=#FF0000] unlink(DELETE_DIR.$file_name);[/color]
    [color=#FF0000]unlink(THUMBS_DIR.$thumb_name);[/color]
// if confirm deletion button has been clicked, delete record
if (array_key_exists('delete', $_POST)) {
  $sql = 'DELETE FROM wallsanddoors WHERE photo_id = ?';
  $stmt = $conn->stmt_init();
  if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $_POST['photo_id']);
    $deleted = $stmt->execute();
    }
  }
These don't:

Code: Select all

if (isset($_GET['photo_id']) && !$_POST) {
    //prepare SQL query
    $sql = 'SELECT photo_id, photo_name, file_name, thumb_name
            FROM wallsanddoors WHERE photo_id = ?';
    //initialize statement
    $stmt = $conn->stmt_init();
    if ($stmt->prepare($sql)) {
        //bind the query parameters
        $stmt->bind_param('i', $_GET['photo_id']);
        //bind the results to variables
        $stmt->bind_result($photo_id, $photo_name, $file_name, $thumb_name);
        //execute the query and fetch the result
        $OK = $stmt->execute();
        $stmt->fetch();
        }
    }
// if confirm deletion button has been clicked, delete record
if (array_key_exists('delete', $_POST)) {
  $sql = 'DELETE FROM wallsanddoors WHERE photo_id = ?';
  $stmt = $conn->stmt_init();
  if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $_POST['photo_id']);
    $deleted = $stmt->execute();
   [color=#FF0000] unlink(DELETE_DIR.$file_name);[/color]
    [color=#FF0000]unlink(THUMBS_DIR.$thumb_name);[/color]
    }
  }

Code: Select all

if (isset($_GET['photo_id']) && !$_POST) {
    //prepare SQL query
    $sql = 'SELECT photo_id, photo_name, file_name, thumb_name
            FROM wallsanddoors WHERE photo_id = ?';
    //initialize statement
    $stmt = $conn->stmt_init();
    if ($stmt->prepare($sql)) {
        //bind the query parameters
        $stmt->bind_param('i', $_GET['photo_id']);
        //bind the results to variables
        $stmt->bind_result($photo_id, $photo_name, $file_name, $thumb_name);
        //execute the query and fetch the result
        $OK = $stmt->execute();
        $stmt->fetch();
        }
    }
// if confirm deletion button has been clicked, delete record
if (array_key_exists('delete', $_POST)) {
  [color=#FF0000] unlink(DELETE_DIR.$file_name);[/color]
  [color=#FF0000]unlink(THUMBS_DIR.$thumb_name);[/color]
  $sql = 'DELETE FROM wallsanddoors WHERE photo_id = ?';
  $stmt = $conn->stmt_init();
  if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $_POST['photo_id']);
    $deleted = $stmt->execute();
    }
  }
I thought maybe the deletion of the database entry was messing up the $file_name variable and causing the unlink to try and delete a non-existent file. However, moving the unlink to a point before the entry is deleted still doesn't work...

Any ideas?

Thanks,
Hendeca

Re: Problems with unlink()

Posted: Tue Jan 06, 2009 9:02 pm
by novice4eva
Your if condition is wrong, you have selected these ($photo_id, $photo_name, $file_name, $thumb_name) when $_POST is NOT SET and you are deleting files after checking array keys of $_POST , so when there are $_POST value the unlink portion is never reached, and when POST values are set in which case the if condition does go to unlink but the portion where you are fetching the filenames and all are never reached.