Jump to content

How to delete an image from the database and folder in PHP


akehn

Recommended Posts

I have a PHP CRUD application and when i delete a row i need it to delete from the MySQL and the image from the uploads folder as well. I have researched and tried dozens of ways with the unlink option but nothing works. If i take out the unlink from my code it will delete fine from the DB. I am new to coding and PHP so any help would be awesome.

The file_path is correct. The uploads is the name of the folder where the image is stored and the $_POST["image"] is the column name in MySQL where the image name is stored.

delete.php

<?php

	//start PHP session
	session_start();

if (!isset($_SESSION['success']))
{
    header("Location: login_page.php");
    die();
}

// check if value was posted
if($_POST){
 
    // include database and object file
    include_once 'config/database.php';

    $file_path = 'uploads/' . $_POST["image"];
    if(unlink($file_path))
 {
	// delete query
	$query = "DELETE FROM myDBname WHERE id = ?";
	$stmt = $con->prepare($query);
	$stmt->bindParam(1, $_POST['object_id']);
 }
	if($stmt->execute()){
		// redirect to read records page and 
		// tell the user record was deleted
		echo "Record was deleted.";
	}else{
		echo "Unable to delete record.";
    }
}

?>

this is the delete button code

					echo "<a delete-id='{$id}' class='btn btn-danger delete-object'>";
					echo "<span class='glyphicon glyphicon-remove'></span> Delete";
					echo "</a>";

This is the javascript for the delete button as well.

	// delete record
	$(document).on('click', '.delete-object', function(){

		var id = $(this).attr('delete-id');

		bootbox.confirm({
		    message: "<h4>Are you sure?</h4>",
		    buttons: {
		        confirm: {
		            label: '<span class="glyphicon glyphicon-ok"></span> Yes',
		            className: 'btn-danger'
		        },
		        cancel: {
		            label: '<span class="glyphicon glyphicon-remove"></span> No',
		            className: 'btn-primary'
		        }
		    },
		    callback: function (result) {

		        if(result==true){
					$.post('delete.php', {
						object_id: id
					}, function(data){
						location.reload();
					}).fail(function() {
						alert('Unable to delete.');
					});
		    	}
			}
		});

		return false;
	});

 

If you need any other info that would help you help me just let me know and i will get that in here ASAP. Thanks again for any help on this.

Link to comment
Share on other sites

If that is the case the "unlink" is returning false. Your code is designed to not delete from the database if the "unlink" fails. Is that what you really want? If so then it is working as coded. If you know the file ALWAYS exists then you need to investigate why the "unlink" is not finding it. Make sure you have error reporting turned on or use a try/catch on the "unlink" to determine why it is failing. Also it makes no sense to put the execute outside the "if" block since the prepare is not executed when that block fails.

Link to comment
Share on other sites

Hello - Thanks for the reply and help. So i commented out the "return false" in the javascript code.. Also moved the execute inside of the if statement. Still didnt work but i enabled logs and now getting this message in the logs.

 [27-Jan-2019 23:23:25 UTC] PHP Notice:  Undefined index: image in /home/xxx/public_html/crud/delete.php on line 18
[27-Jan-2019 23:23:25 UTC] PHP Warning:  unlink(uploads/): Is a directory in /home/xxx/public_html/crud/delete.php on line 19

Here is my new delete.php file.

<?php

	//start PHP session
	session_start();

if (!isset($_SESSION['success']))
{
    header("Location: login_page.php");
    die();
}

// check if value was posted
if($_POST){
 
    // include database and object file
    include_once 'config/database.php';

    $file_path = 'uploads/' . $_POST["image"];
    if(unlink($file_path))
 {
	// delete query
	$query = "DELETE FROM dhospital WHERE id = ?";
	$stmt = $con->prepare($query);
	$stmt->bindParam(1, $_POST['object_id']);
 
	if($stmt->execute()){
		// redirect to read records page and 
		// tell the user record was deleted
		echo "Record was deleted.";
	}else{
		echo "Unable to delete record.";
    }
}
}

?>

I am not sure what those errors mean in the logs. I am just a beginner coder. Thanks again for the help.

Link to comment
Share on other sites

16 minutes ago, akehn said:

27-Jan-2019 23:23:25 UTC] PHP Warning:  unlink(uploads/): Is a directory in /home/xxx/public_html/crud/delete.php on line 19

That is telling you that you are attempting to delete a path with no file name, just the directory.

There is no file name because $_POST['image'] does not exist, which is what the othere message tells you

18 minutes ago, akehn said:

 [27-Jan-2019 23:23:25 UTC] PHP Notice:  Undefined index: image in /home/xxx/public_html/crud/delete.php on line 18

 

Link to comment
Share on other sites

Quote

I tried that print code in my delete.php but did not do anything. Not sure if i placed it correctly. I moved it to the php file that the delete button is on and does show on there.

This is my read_template.php that contains the delete button.

Quote

<?php
echo "<div class='overflow-hidden container'>";

	?>

<a href="login_page.php">Login</a>

	<?php 
			if(!isset($_SESSION['success']))
			{
				echo "";
			}
			else
			{
				echo "<button class='btn btn-danger float-md-right margin-bottom-1em margin-bottom-1em' id='delete-selected'>
				<span class='glyphicon glyphicon-remove-circle'></span> Delete Selected </button>";
			}
	
			if(!isset($_SESSION['success']))
			{
				echo "";
			}
			else
			{
				echo "<a href='create.php' class='btn btn-primary float-md-right margin-right-1em'>
				<span class='glyphicon glyphicon-plus'></span> Create Record </a>";
			}
		?>

		<a href='export_csv.php' class='btn btn-info float-md-right margin-bottom-1em margin-right-1em'>
			<span class='glyphicon glyphicon-download'></span> Export CSV
		</a>

</div>

<?php

//check if more than 0 record found
if($num>0){
	echo "<div class='container-fluid'>";
    echo "<table width='100%' class='table table-striped table-bordered table-hover' id='table_id'>";//start table

		//creating our table heading
		echo "<thead>";
        echo "<tr>";
			echo "<th class='text-align-center'><input type='checkbox' id='checker' /></th>";
			echo "<th>ID</th>";
			echo "<th>Image</th>";
			echo "<th>Date Found</th>";
            echo "<th>Item Name</th>";
            echo "<th>Item Description</th>";
			echo "<th>Action</th>";
		echo "</tr>";
		echo "</thead>";
		echo "<tbody>";

        // retrieve our table contents
		// fetch() is faster than fetchAll()
		// http://stackoverflow.com/questions/2770630/pdofetchall-vs-pdofetch-in-a-loop
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
            // extract row
            // this will make $row['firstname'] to
            // just $firstname only
            extract($row);

            //creating new table row per record
            echo "<tr>";
				echo "<td class='text-align-center'><input type='checkbox' name='item[]' class='checkboxes' value='{$id}' /></td>";
				echo "<td>{$id}</td>";
				echo "<td><img height='auto' width='35%' src='uploads/{$image}'/></td>";
                echo "<td>{$created}</td>";
                echo "<td>{$item_name}</td>";
                echo "<td>{$item_description}</td>";
				// echo "<td>{$category_name}</td>";
				echo "<td>";

					// read one record
					echo "<a href='read_one.php?id={$id}' class='btn btn-primary margin-right-1em'>";
						echo "<span class='glyphicon glyphicon-eye-open'></span> Claim";
					echo "</a>";

					if(!isset($_SESSION['success']))
					{
						echo "";
					}
					else
					{
					// update record
					echo "<a href='update.php?id={$id}' class='btn btn-info margin-right-1em'>";
						echo "<span class='glyphicon glyphicon-edit'></span> Edit";
					echo "</a>";
					}

					if(!isset($_SESSION['success']))
					{
						echo "";
					}
					else
					{
					// delete record
					echo "<a delete-id='{$id}' class='btn btn-danger delete-object'>";
						echo "<span class='glyphicon glyphicon-remove'></span> Delete";
					echo "</a>";
					}

				echo "</td>";
            echo "</tr>";
        }

	//end table
	echo "</tbody>";
    echo "</table>";
	echo "</div>";
}

//if no records found
else{
	echo "<div class='alert alert-danger'>";
		echo "No records found.";
	echo "</div>";
}

echo '<pre>', print_r($_POST, 1), '</pre>';

?>

 

 

 

Screen Shot 2019-01-27 at 5.51.18 PM.png

Link to comment
Share on other sites

Put it just before the 'if (unlink...'.

 

As an aside:

// check if value was posted
if($_POST){

will always be true. Perhaps you should check:

// check if value was posted
if(isset($_POST["image"]){

instead

Edited by gw1500se
Link to comment
Share on other sites

Hello - thanks for hanging with me so far. So i put the "Print" code right above the unlink.  I also modified the second part you said. Still not working but now i have no errors which is weird. It does not print anything to the screen either. I checked my PHP ini settings/options from Godaddy and i do have "display_errors" & "error_reporting" on as well. 

I will display below my delete.php, index.php,  read_template.php, and layout_footer.php

delete.php

<?php

	//start PHP session
	session_start();

if (!isset($_SESSION['success']))
{
    header("Location: login_page.php");
    die();
}

// check if value was posted
if(isset($_POST["image"])){
 
    // include database and object file
	include_once 'config/database.php';
	
	echo '<pre>', print_r($_POST, 1), '</pre>';
	
	$file_path = "uploads/" . $_POST["image"];
	echo '<pre>', print_r($_POST, 1), '</pre>';
    if(unlink($file_path))
 {
	// delete query
	$query = "DELETE FROM dhospital WHERE id = ?";
	$stmt = $con->prepare($query);
	$stmt->bindParam(1, $_POST['object_id']);
 
	if($stmt->execute()){
		// redirect to read records page and 
		// tell the user record was deleted
		echo "Record was deleted.";
	}else{
		echo "Unable to delete record.";
    }
}

}


?>

 

index.php

<?php
// include core configuration
include 'config/core.php';

// include database connection
include 'config/database.php';

session_start();

// action variable
$action = isset($_GET['action']) ? $_GET['action'] : "";

// page header
$page_title="Lost & Found";
include_once "layout_head.php";

// if it was redirected from delete.php
if($action=='deleted'){
	echo "<div class='alert alert-info'>Record was deleted.</div>";
}

//select all data
$query = "SELECT p.id, p.item_name, p.item_description, p.created, p.image, c.item_name as category_name
			FROM dhospital p
				LEFT JOIN categories c
					ON p.category_id=c.id
			ORDER BY id DESC
			LIMIT :from_record_num, :records_per_page";

$stmt = $con->prepare($query);
$stmt->bindParam(":from_record_num", $from_record_num, PDO::PARAM_INT);
$stmt->bindParam(":records_per_page", $records_per_page, PDO::PARAM_INT);
$stmt->execute();

//this is how to get number of rows returned
$num = $stmt->rowCount();

// to identify page for paging
$page_url="index.php?";

// include the read template
include_once "read_template.php";

// page footer
include_once "layout_foot.php";
?>

 

read_template.php

<?php
echo "<div class='overflow-hidden container'>";

	?>

<a href="login_page.php">Login</a>

	<?php 
			if(!isset($_SESSION['success']))
			{
				echo "";
			}
			else
			{
				echo "<button class='btn btn-danger float-md-right margin-bottom-1em margin-bottom-1em' id='delete-selected'>
				<span class='glyphicon glyphicon-remove-circle'></span> Delete Selected </button>";
			}
	
			if(!isset($_SESSION['success']))
			{
				echo "";
			}
			else
			{
				echo "<a href='create.php' class='btn btn-primary float-md-right margin-right-1em'>
				<span class='glyphicon glyphicon-plus'></span> Create Record </a>";
			}
		?>

		<a href='export_csv.php' class='btn btn-info float-md-right margin-bottom-1em margin-right-1em'>
			<span class='glyphicon glyphicon-download'></span> Export CSV
		</a>

</div>

<?php

//check if more than 0 record found
if($num>0){
	echo "<div class='container-fluid'>";
    echo "<table width='100%' class='table table-striped table-bordered table-hover' id='table_id'>";//start table

		//creating our table heading
		echo "<thead>";
        echo "<tr>";
			echo "<th class='text-align-center'><input type='checkbox' id='checker' /></th>";
			echo "<th>ID</th>";
			echo "<th>Image</th>";
			echo "<th>Date Found</th>";
            echo "<th>Item Name</th>";
            echo "<th>Item Description</th>";
			echo "<th>Action</th>";
		echo "</tr>";
		echo "</thead>";
		echo "<tbody>";

        // retrieve our table contents
		// fetch() is faster than fetchAll()
		// http://stackoverflow.com/questions/2770630/pdofetchall-vs-pdofetch-in-a-loop
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
            // extract row
            // this will make $row['firstname'] to
            // just $firstname only
            extract($row);

            //creating new table row per record
            echo "<tr>";
				echo "<td class='text-align-center'><input type='checkbox' name='item[]' class='checkboxes' value='{$id}' /></td>";
				echo "<td>{$id}</td>";
				echo "<td><img height='auto' width='35%' src='uploads/{$image}'/></td>";
                echo "<td>{$created}</td>";
                echo "<td>{$item_name}</td>";
                echo "<td>{$item_description}</td>";
				// echo "<td>{$category_name}</td>";
				echo "<td>";

					// read one record
					echo "<a href='read_one.php?id={$id}' class='btn btn-primary margin-right-1em'>";
						echo "<span class='glyphicon glyphicon-eye-open'></span> Claim";
					echo "</a>";

					if(!isset($_SESSION['success']))
					{
						echo "";
					}
					else
					{
					// update record
					echo "<a href='update.php?id={$id}' class='btn btn-info margin-right-1em'>";
						echo "<span class='glyphicon glyphicon-edit'></span> Edit";
					echo "</a>";
					}

					if(!isset($_SESSION['success']))
					{
						echo "";
					}
					else
					{
					// delete record
					echo "<a delete-id='{$id}' class='btn btn-danger delete-object'>";
						echo "<span class='glyphicon glyphicon-remove'></span> Delete";
					echo "</a>";
					}

				echo "</td>";
            echo "</tr>";
        }

	//end table
	echo "</tbody>";
    echo "</table>";
	echo "</div>";
}

//if no records found
else{
	echo "<div class='alert alert-danger'>";
		echo "No records found.";
	echo "</div>";
}

?>

 

layout_footer.php (javascript entries)

<a href="logout.php">Logout</a>
	</div>
	<!-- /container -->

      <!-- jQuery -->
      <script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<!-- bootbox for confirm pop up -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>


      <!-- Bootsrap 4 -->
	  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.bundle.min.js"></script>

    
    <!-- DataTables JavaScript -->
	<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.18/r-2.2.2/datatables.min.js"></script>

<script type='text/javascript'>
$(document).ready(function() {
	//check/uncheck script
	$(document).on('click', '#checker', function(){
		$('.checkboxes').prop('checked', $(this).is(':checked'));
	});

	// delete record
	$(document).on('click', '.delete-object', function(){

		var id = $(this).attr('delete-id');

		bootbox.confirm({
		    message: "<h4>Are you sure?</h4>",
		    buttons: {
		        confirm: {
		            label: '<span class="glyphicon glyphicon-ok"></span> Yes',
		            className: 'btn-danger'
		        },
		        cancel: {
		            label: '<span class="glyphicon glyphicon-remove"></span> No',
		            className: 'btn-primary'
		        }
		    },
		    callback: function (result) {

		        if(result==true){
					$.post('delete.php', {
						object_id: id
					}, function(data){
						location.reload();
					}).fail(function() {
						alert('Unable to delete.');
					});
		    	}
			}
		});

		// return false;
	});

	// delete selected records
	$(document).on('click', '#delete-selected', function(){

		var at_least_one_was_checked = $('.checkboxes:checked').length > 0;

		if(at_least_one_was_checked){

			bootbox.confirm({
				message: "<h4>Are you sure?</h4>",
				buttons: {
					confirm: {
						label: '<span class="glyphicon glyphicon-ok"></span> Yes',
						className: 'btn-danger'
					},
					cancel: {
						label: '<span class="glyphicon glyphicon-remove"></span> No',
						className: 'btn-primary'
					}
				},
				callback: function (result) {

					if(result==true){
						//get converts it to an array
						var del_checkboxes = $('.checkboxes:checked').map(function(i,n) {
							return $(n).val();
						}).get();

						if(del_checkboxes.length==0) {
							del_checkboxes = "none";
						}

						$.post("delete_selected.php", {'del_checkboxes[]': del_checkboxes},
							function(response) {
								// refresh page
								location.reload();
							});
					}
				}
			});
		}

		else{
			bootbox.alert("Please select at least one record to delete.");
		}
	});
});
</script>

<script>
$(document).ready( function () {
    $('#table_id').DataTable({
		responsive: true
	});
} );
</script>

</body>
</html>

 

Link to comment
Share on other sites

The forms i have in my project are in the update.php, create.php, login.php, read_one.php. The delete button though is not inside any of the forms. 

update.php

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"] . "?id={$id}");?>" method="post" enctype="multipart/form-data">

create.php

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" enctype="multipart/form-data">

login.php

 <form method="POST" action="login_code.php">

read_one.php

<form method="POST" action="emailForm.php">

 

When i just have this code in my delete.php file it will delete from the MySQL DB just fine (But not from the uploads folder). Its when i added in the unlink feature it stops working all together. 

Original delete.php code

<?php
	//start PHP session
	session_start();

if (!isset($_SESSION['success']))
{
    header("Location: login_page.php");
    die();
}

// check if value was posted
if($_POST){
 
    // include database and object file
    include_once 'config/database.php';
 
	// delete query
	$query = "DELETE FROM dhospital WHERE id = ?";
	$stmt = $con->prepare($query);
	$stmt->bindParam(1, $_POST['object_id']);
	
	if($stmt->execute()){
		// redirect to read records page and 
		// tell the user record was deleted
		echo "Record was deleted.";
	}else{
		echo "Unable to delete record.";
	}
}
?>

 

Screen Shot 2019-01-28 at 11.28.59 AM.png

Link to comment
Share on other sites

gw1500se - Sorry i am a complete beginner at this. I do not have any form that has the action of the delete.php in it. The only forms i have are the ones above i pasted. I found a few things that might be what your looking for?

In my index.php

// action variable
$action = isset($_GET['action']) ? $_GET['action'] : "";

// page header
$page_title="Lost & Found";
include_once "layout_head.php";

// if it was redirected from delete.php
if($action=='deleted'){
	echo "<div class='alert alert-info'>Record was deleted.</div>";
}

In my layout_footer.php

	// delete record
	$(document).on('click', '.delete-object', function(){

		var id = $(this).attr('delete-id');

		bootbox.confirm({
		    message: "<h4>Are you sure?</h4>",
		    buttons: {
		        confirm: {
		            label: '<span class="glyphicon glyphicon-ok"></span> Yes',
		            className: 'btn-danger'
		        },
		        cancel: {
		            label: '<span class="glyphicon glyphicon-remove"></span> No',
		            className: 'btn-primary'
		        }
		    },
		    callback: function (result) {

		        if(result==true){
					$.post('delete.php', {
						object_id: id
					}, function(data){
						location.reload();
					}).fail(function() {
						alert('Unable to delete.');
					});
		    	}
			}
		});

		// return false;
	});

 

Barand - I changed the $_POST['image']  to $_POST['object_id'] and not get the following error.

PHP Warning:  unlink(uploads/34): No such file or directory in /home/public_html/crud/delete.php on line 22

So the unlink(uploads/34) is the ID looks like. How would i switch that to the image? 

 

Screen Shot 2019-01-28 at 1.22.53 PM.png

Screen Shot 2019-01-28 at 1.21.25 PM.png

Screen Shot 2019-01-28 at 1.27.15 PM.png

Link to comment
Share on other sites

Thanks... Sounds logical just knowing how to do that is my issue now. Any hints on it? Does it need to be all re-coded to do that or is it as simple as a few lines of code or change a few existing lines? 

Thanks to the both of you who helped on this.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.