akehn Posted January 27, 2019 Share Posted January 27, 2019 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. Quote Link to comment Share on other sites More sharing options...
gw1500se Posted January 27, 2019 Share Posted January 27, 2019 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. Quote Link to comment Share on other sites More sharing options...
akehn Posted January 27, 2019 Author Share Posted January 27, 2019 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. Quote Link to comment Share on other sites More sharing options...
Barand Posted January 27, 2019 Share Posted January 27, 2019 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 Quote Link to comment Share on other sites More sharing options...
akehn Posted January 27, 2019 Author Share Posted January 27, 2019 Sorry new to this. What would i add or change then? I do have an uploads folder with the image JPG in it. Also the $_POST['image'] is the column name in the MySQL that holds the name of the image. See pictures below. Quote Link to comment Share on other sites More sharing options...
Barand Posted January 28, 2019 Share Posted January 28, 2019 "image" may be the column name in your database but, what matters here, it isn't the name of one of the form inputs that you are POSTing. You can use this to see what is being posted echo '<pre>', print_r($_POST, 1), '</pre>'; Quote Link to comment Share on other sites More sharing options...
akehn Posted January 28, 2019 Author Share Posted January 28, 2019 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>'; ?> Quote Link to comment Share on other sites More sharing options...
gw1500se Posted January 28, 2019 Share Posted January 28, 2019 (edited) 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 January 28, 2019 by gw1500se Quote Link to comment Share on other sites More sharing options...
akehn Posted January 28, 2019 Author Share Posted January 28, 2019 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> Quote Link to comment Share on other sites More sharing options...
gw1500se Posted January 28, 2019 Share Posted January 28, 2019 If you are not getting any output from the print then it is obvious that '$_POST["Image"]' is not set. What file is the 'action' parameter set to in your form tag? Quote Link to comment Share on other sites More sharing options...
akehn Posted January 28, 2019 Author Share Posted January 28, 2019 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."; } } ?> Quote Link to comment Share on other sites More sharing options...
gw1500se Posted January 28, 2019 Share Posted January 28, 2019 We already explained why it is working the way it is. We are trying to help you figure out why $_POST does not contain what you expect. Were is the form that has delete.php as the action? Quote Link to comment Share on other sites More sharing options...
Barand Posted January 28, 2019 Share Posted January 28, 2019 On 1/27/2019 at 4:46 PM, akehn said: $.post('delete.php', { object_id: id }, function(data){ location.reload(); }).fail(function() { alert('Unable to delete.'); }); That javascript ajax call is sending the id in $_POST['object_id'], not in $_POST['image'] Quote Link to comment Share on other sites More sharing options...
akehn Posted January 28, 2019 Author Share Posted January 28, 2019 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? Quote Link to comment Share on other sites More sharing options...
gw1500se Posted January 28, 2019 Share Posted January 28, 2019 The number 34 is the ID not the file name. As stated earlier you need to delete from the DB using the ID and delete the file using the filename. Two different operations requiring 2 different pieces of data. Quote Link to comment Share on other sites More sharing options...
Barand Posted January 28, 2019 Share Posted January 28, 2019 Just guessing, but it looks as though 34 may be the id of the record containing the image to be deleted. Therefore you need to retrieve record 34 to get the image file name unlink the image file delete record 34 Quote Link to comment Share on other sites More sharing options...
akehn Posted January 28, 2019 Author Share Posted January 28, 2019 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.