Удалить несколько записей с помощью флажков

Я пытаюсь понять, как удалить несколько записей с помощью флажков. У меня есть таблица на моей странице, которая получает данные из базы данных. В первом столбце каждой строки есть флажок, который выглядит следующим образом:

<input type="checkbox" name="checked[]" value='.$row['UserId'].' class="checkbox" />

Мой код выглядит следующим образом:

<?php
// get required includes
require_once(ROOT_PATH.'connections/mysql.php');
require_once(ROOT_PATH.'admin/controls/users_az/error_messages.php');

// declare variables
$msg = '';

// ------------------------------------------------------------------
// DELETE SELECTED USERS
// ------------------------------------------------------------------
if(isset($_POST['btnDeleteSelected']) && isset($_POST['checked']))
{
$checked = array_map(mysqli_real_escape_string($conn, $_POST['checked']));
$list = "'" . implode("','", $checked) . "'";

$delete_selected = mysqli_query($conn, "DELETE FROM users WHERE UserId IN ($list)")
or die($dataaccess_error);

if($delete_selected)
{
    $msg = mysqli_affected_rows($delete_selected).' '.$msg_success;
}
}
elseif(isset($_POST['btnDeleteSelected']) && !isset($_POST['checked']))
{
$msg = $msg_error;
}
?>

Проблема: это, естественно, не работает. Я впервые пытаюсь это сделать.

Вопрос: Я на правильном пути? Как мне изменить это, чтобы оно работало?


person Community    schedule 26.10.2010    source источник
comment
Сможете ли вы ввести полную строку SQL после попытки добавить идентификаторы?   -  person mway    schedule 27.10.2010
comment
И да, вы можете сделать это так. Тем не менее, вы должны сначала избежать идентификаторов, используя mysql_real_escape_string(); в противном случае кто-то может установить значение флажка на что-нибудь неприятное (внедрение sql).   -  person mway    schedule 27.10.2010
comment
Определить не получается. Есть ли ошибки?   -  person Saul    schedule 27.10.2010
comment
"Это не работает" расплывчато ... Вы получаете сообщение об ошибке? Вы должны попробовать сгенерированную строку SQL в своем клиенте mysql, чтобы проверить ее достоверность.   -  person greg0ire    schedule 27.10.2010
comment
@mway: кстати, бессмысленно запускать mysql_real_escape_string() со значением INT, потому что значение сначала преобразуется в INT, его не нужно дезинфицировать с помощью mysql_real_escape_string(), на самом деле это может просто вызвать проблемы.   -  person Zubair1    schedule 26.04.2011
comment
Естественно это не работает. Что это значит не работает? И почему это естественно?   -  person Lightness Races in Orbit    schedule 08.07.2011


Ответы (3)


Это приведет к ошибке:

$checked = array_map(mysqli_real_escape_string($conn, $_POST['checked']));

Потому что array_map хочет, чтобы обратный вызов был первым, а массив - вторым аргументом. В остальном настройка довольно хороша, но поскольку mysqli_real_escape_string требуется соединение, array_map или array_walk не так удобны, вы можете попробовать обычный foreach цикл. В качестве альтернативы, если идентификаторы всегда целые числа:

$checked = array_map('intval',$_POST['checked']);

... и опустите кавычки вокруг значений в операторе implode (попробуйте передать целые числа mysql для целочисленных столбцов, строки для других столбцов (char / date / blob / text)).

person Wrikken    schedule 26.10.2010
comment
Кажется, сейчас он работает, но я все еще получаю следующую ошибку: Предупреждение: mysqli_affected_rows () ожидает, что параметр 1 будет mysqli, логическим значением, заданным в C: \ wamp \ www \ MyCMS \ admin \ controls \ users_az \ delete_selected.php в строке 22 - person ; 27.10.2010
comment
Ага, следующая проблема: mysqli_query вернет true для успешных DELETE запросов. Вы не подаете mysqli_affected_rows результат запроса, вы даете ему соединение (mysqli_affected_rows($conn);) - person Wrikken; 27.10.2010

Просто убедитесь, что каждый элемент вашего массива является целым числом (например, ctype_digit ()), а затем вы можете использовать implode без кавычек, например:

$list = implode(", ", $checked);
person greg0ire    schedule 26.10.2010
comment
Предупреждение: mysqli_real_escape_string () ожидает, что параметр 2 будет строкой, массивом, указанным в C: \ wamp \ www \ MyCMS \ admin \ controls \ users_az \ delete_selected.php в строке 14 Предупреждение: array_map () ожидает как минимум 2 параметра, 1 из которых указан в C: \ wamp \ www \ MyCMS \ admin \ controls \ users_az \ delete_selected.php в строке 14 Предупреждение: implode () [function.implode]: недопустимые аргументы переданы в C: \ wamp \ www \ MyCMS \ admin \ controls \ users_az \ delete_selected.php в строке 16 - person ; 27.10.2010
comment
Да, ваш оператор array_map () неверен: он должен иметь 2 параметра вместо одного. - person greg0ire; 27.10.2010

С PHP> = 5.3 вы можете использовать анонимную функцию:

$checked = array_map(function($s) use ($conn) { return mysqli_real_escape_string($conn, $s); }, $_POST['checked']);

В противном случае вы можете выполнить обратный вызов пользовательской функции:

$checked = array_map('myescape', $_POST['checked']);
function myescape($s)
{
    global $conn;
    return mysqli_real_escape_string($conn, $s);
}

или просто зацикливать вручную.

person webbiedave    schedule 26.10.2010
comment
Супер! Мне очень нравится анонимная функция. Он очень элегантный и изысканный. Хотел бы я понять фигурные скобки в синтаксисе. - person ; 27.10.2010
comment
Фигурные скобки просто инкапсулируют определение функции (как и с любой другой определяемой пользователем функцией). - person webbiedave; 27.10.2010