I am using Bootstrap Data Table and want to delete multiple users from the database. I am able to delete 1 user at a time with no problem but once I try to delete more than one I run into issues and I cannot find any errors.
Here is the AJAX code:
function removeRow(){
var url = 'remove-user.php';
var id = document.getElementById("user-id").value;
var data = 'userID=' + id;
$.ajax({
url: url,
data: data,
cache: false,
error: function(e){
alert(e);
},
success: function () {
alert(data);
var selects = $('#users-table').bootstrapTable('getSelections');
ids = $.map(selects, function (row) {
return row.id;
});
$('#users-table').bootstrapTable('remove', {
field: 'id',
values: ids
});
}
});
}
Example: The data in the url will be userID=1,2
Here is the remove-user.php code:
require("../config.php");
if(isset($_GET['userID'])) {
try{
$userID = $_GET['userID'];
$query = "DELETE FROM users WHERE user_id IN (:userID)";
$stmt = $db->prepare($query);
$stmt->bindParam(":userID", $userID, PDO::PARAM_INT);
$stmt->execute();
$user_removed = 'User was successfully deleted.';
$_SESSION['user_removed'] = $user_removed;
} catch (Exception $e){
echo 'The following error occured: <br/>'.$e->getMessage();
}
}
When I check more than one user the first user will get delete, but not the others. Are there any mistakes in my code?
Again, what I am looking to do is delete multiple users by selecting them from the table and passing the value of a hidden input which contains multiple ids like this - userID=1,2. When I go to the remove-user.php
page directly and echo the GET it displays as 1,2 no quotes. If I change my delete to specify the IDs instead of binding a parameter everything works fine. I'm really not sure why its not working.
Please let me know if I need to give more info.
So I was finally able to find a solution which I thought I tried. I think the reason why it wasn't working might have something to do with me trying to use bindParam
.
Here is what I changed my remove-user.php
code to:
try{
$ids = array($_GET['userID']);
$inQuery = implode(',', $ids);
$stmt = $db->prepare(
'DELETE
FROM users
WHERE user_id IN(' . $inQuery . ')'
);
$stmt->execute($ids);
$count = $stmt->rowCount();
$user_removed = ''.$count.' user(s) deleted successfully.';
$_SESSION['user_removed'] = $user_removed;
} catch (Exception $e){
$error = '<strong>The following error occured:</strong>'.$e->getMessage();
$_SESSION['error'] = $error;
}
The problem is how you're passing data to your PDOStatement.
// assign :userID to $userID which should be cast into an int.
$stmt->bindParam(":userID", $userID, PDO::PARAM_INT);
This is how I might approach similar (assuming that you have checked appropriate permissions):
$ids_in = $_GET['userID'];
$ids_cast = array();
foreach(explode(',', $ids_in) as $id) {
// casting to an int means that SQL injection can't work, though I wonder if
// allowing a user to delete an arbitrary number of IDs is a good thing.
$ids_cast[] = intval($id);
}
// gets rid of bad strings &ct.
$ids_filtered = implode(',',array_filter($ids_cast));
if(!$ids_filtered) die('No valid IDs');
$query = "DELETE FROM users WHERE user_id IN ($ids_filtered)";
// run query.
In your SQL query :userID
parameter is string containing sequence of ids separated by comma (for example, 1,2
).
$query = "DELETE FROM users WHERE user_id IN (:userID)";
But when binding you define your parameter as integer passing PDO::PARAM_INT
argument in bindParam
function.
$stmt->bindParam(":userID", $userID, PDO::PARAM_INT);
Try to use
$stmt->bindParam(":userID", $userID, PDO::PARAM_STR);
instead.