Изтрийте множество записи с помощта на квадратчета за отметка

Опитвам се да разбера как мога да изтрия множество записи с помощта на квадратчета за отметка. Имам таблица на моята страница, която получава данните от базата данни. Първата колона за всеки ред има квадратче за отметка, което изглежда по следния начин:

<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