php delete file using unlink before database row update

2.5k views Asked by At

I'm setting up a CRUD and realized that I will need to delete the image that's stored in a directory if the user wants to upload a new image.

I have a webpage with a form that brings the information from the database row using the id, then posts the updated values to a script which is where the trouble is.

I'm trying to find the file that needs to be deleted with this:

$target_dir = "images/photo/";
$del_image = $_FILES["image"];

And trying to set the permissions of the file with this:

$change = chmod($del_image,0644);

Then trying the delete the file with this:

$delete = unlink($target_dir.$image);

Before I update everything with this:

$target_file = $target_dir . basename($_FILES["image"]["name"]);
$file = $target_dir . basename($_FILES["ud_image"]["name"]);
$uploadOk = 1;
if (move_uploaded_file($_FILES["ud_image"]["tmp_name"], $file))
{
echo '<script type="text/javascript">';
echo 'alert("News Items Saved")';
echo '</script>';
} else {
    echo "Sorry, there was an error with your file.";
}
$id = intval($_GET['id']);
$ud_headline = $_POST["ud_headline"]; //mysql_real_escape_string()
$ud_body = $_POST["ud_body"]; //mysql_real_escape_string()
$ud_image = $_POST["ud_image"]; //mysql_real_escape_string()


$query="UPDATE news SET 
    headline = '$ud_headline',
    body = '$ud_body',
    image = '$ud_image' 
    WHERE id='$ud_id'";


$mysqli->query($query)or die($mysqli->error);
if($mysqli->affected_rows>=1){
echo "<script type='text/javascript'>";
echo "alert('News Item Updated');";
echo 'document.location.href = "/pc.v.2/admin-news.php";';
echo "</script>;";
}
else
{
echo "<script type='text/javascript'>";
echo "alert('News Item Not Updated'. $mysqli->error);";
echo "</script>";
//echo "Error deleting record: " . $conn->error;
}

The errors I get are telling me that I'm not even finding the directory correctly, let alone the file.

This is the form:

<form action="update.php" method="post" class="newNews">
<input type="hidden" name="ud_id" value="<?=$id;?>">
<!-- <input type="hidden" name="old_id" value="<?=$image;?>"> -->

<label for="title">Title</label>
<input type="text" name="ud_headline" value="<?=$headline;?>"/><br />

<label for="text">Body</label>
<textarea name="ud_body" rows="15" cols="21" value=""><?=$body;?></textarea><br />

<p>Current Photo</p>
<img src="<?=$target_dir.$image?>" alt=''><br />

<input type="file" name="ud_image" class="newsImage" ><br />

<input type="submit" name="submit" value="Update news item" class='addNew' />

</form>

How can I fix this?

1

There are 1 answers

8
light On

PHP's move_uploaded_file() will actually overwrite the old file, so you don't actually need to perform the redundant unlink().

Since we don't have access to your server, we can't tell you exactly what went wrong. But it could be one (or more) of these:

  • Ensure that your $target_dir is prepended with $_SERVER['DOCUMENT_ROOT'].'/' or the root path of your server, e.g. '/var/www/'.
  • Ensure the folders actually exist.
  • Ensure your webserver has write permissions to the folders.
  • (a good practice) Check for file errors before upload

I'd do this to troubleshoot:

// Derive target paths
$target_dir = $_SERVER['DOCUMENT_ROOT'].'/images/photo/';
$target_path = $target_dir . basename($_FILES["ud_image"]["name"]);

// Check target dir exists and is writable
if (!file_exists($target_dir )) {
    // Try to automatically create the folders
    umask(0);
    if (!mkdir($target_dir , 0777, true)) { // or whatever permissions
        // Do your error handling here
        echo 'Sorry, target directory does not exist and we could not create it automatically.';
        exit(1);
    }
}
if (!is_writable($target_dir)) {
    // Do your error handling here
    echo 'Sorry, the directory is not writable.';
    exit(1);
}

// Check for file errors
if (!isset($_FILES["ud_image"]["tmp_name"])) {
    echo 'Sorry, no upload file detected.';
    exit(1);
}
if ($_FILES["ud_image"]["error"] > 0) {
    echo 'Sorry, there was an error with the file. Error code: '.$_FILES["ud_image"]["error"]);
    exit(1);
}

// Move uploaded file
if (!move_uploaded_file($_FILES["ud_image"]["tmp_name"], $target_path)) {
    // Do your error handling here
    echo "Sorry, there was an error with the upload operation.";
    exit(1);
}

// If you reach here, the upload should have succeeded. Go on to do whatever else you need to do
echo '<script>alert('News Item saved')</script>';

Just by the way, echo statements in server-side code is probably not a good idea, but that's besides the point. It's best to keep presentation and logic separate for maintainability and ease of troubleshooting.