Проблема при попытке использовать IN() в wpdb

у меня есть это:

$villes = '"paris","fes","rabat"';
$sql    = 'SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN(%s)';
$query  = $wpdb->prepare($sql, $villes);

когда я делаю echo $query;, я получаю:

SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN('\"CHAPELLE VIVIERS \",\"LE MANS \",\"QUEND\"')

у меня проблема в том, что $wpdb добавить ' в IN('...')

может кто поможет, спасибо


person mgraph    schedule 17.05.2012    source источник


Ответы (4)


Попробуйте этот код (ИСПРАВЛЕНО):

// Create an array of the values to use in the list
$villes = array("paris", "fes", "rabat");    

// Generate the SQL statement.
// The number of %s items is based on the length of the $villes array
$sql = "
  SELECT DISTINCT telecopie
  FROM `comptage_fax`
  WHERE `ville` IN(".implode(', ', array_fill(0, count($villes), '%s')).")
";

// Call $wpdb->prepare passing the values of the array as separate arguments
$query = call_user_func_array(array($wpdb, 'prepare'), array_merge(array($sql), $villes));

echo $query;
person DaveRandom    schedule 17.05.2012
comment
Обратите внимание, что это, возможно, слишком сложный подход, но он дает вам возможность изменять содержимое массива, и код будет соответствующим образом адаптироваться без каких-либо изменений. Таким образом, вы можете заполнить $villes 30 городами вместо 3, и это все равно будет работать. - person DaveRandom; 17.05.2012
comment
Возможно, вы захотите добавить это в кодекс или отправить патч для ядра, который позволит вам использовать этот метод для оператора IN. - person Nick Budden; 26.03.2013
comment
Как я могу добавить оператор AND рядом с областью WHERE. ГДЕ ville IN(.implode(', ', array_fill(0, count($villes), '%s')).) И table_name.name = '%s' - person Faysal Haque; 12.03.2015
comment
Спасибо за ваш код, он помогает мне в том, что мне нужно :) вот мое решение: stackoverflow.com/a/29000133/1993427 - person Faysal Haque; 12.03.2015
comment
Теперь вы можете использовать расширение, чтобы сделать код немного чище, если ваш массив является последним элементом в $prepare: $wpdb->prepare($sql,...$ville); - person Aaron Harun; 19.05.2017
comment
Примечание PHP: wpdb::prepare был вызван ‹strong›неправильно‹/strong›. Неподдерживаемый тип значения (массив). См. ‹a href=wordpress.org/support/article/debugging-in -wordpress/ в WordPress‹/a› для получения дополнительной информации. (Это сообщение было добавлено в версии 4.8.2.) в E:\XAMPP\htdocs\mr-assistant\wp-includes\functions.php в строке 5167. - person Shapon Pal; 20.07.2020

В WordPress уже есть функция для этой цели, см. esc_sql(). Вот определение этой функции:

Экранирует данные для использования в запросе MySQL. Обычно вы должны готовить запросы, используя wpdb::prepare(). Иногда требуется или полезно использовать точечное экранирование. Одним из примеров является подготовка массива для использования в предложении IN.

Вы можете использовать его следующим образом:

$villes = ["paris", "fes", "rabat"];
$villes = array_map(function($v) {
    return "'" . esc_sql($v) . "'";
}, $villes);
$villes = implode(',', $villes);
$query = "SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN (" . $villes . ")"
person Turgut Sarıçam    schedule 16.04.2016
comment
Мне нравится этот ответ больше, чем принятый ответ из-за его простоты - person Greeso; 21.03.2017
comment
Мне нравится этот. Хорошо использует функцию WordPress - person shariqkhan; 14.12.2020

ФУНКЦИЯ:

function escape_array($arr){
    global $wpdb;
    $escaped = array();
    foreach($arr as $k => $v){
        if(is_numeric($v))
            $escaped[] = $wpdb->prepare('%d', $v);
        else
            $escaped[] = $wpdb->prepare('%s', $v);
    }
    return implode(',', $escaped);
}

ИСПОЛЬЗОВАНИЕ:

$arr = array('foo', 'bar', 1, 2, 'foo"bar', "bar'foo");

$query = "SELECT values
FROM table
WHERE column NOT IN (" . escape_array($arr) . ")";

echo $query;

РЕЗУЛЬТАТ:

SELECT values
FROM table
WHERE column NOT IN ('foo','bar',1,2,'foo\"bar','bar\'foo')

Может быть или не быть более эффективным, однако его можно использовать повторно.

person Greenzilla    schedule 03.06.2015

Функция prepare также принимает array в качестве второго параметра.

Вы можете попробовать преобразовать $villes следующим образом:

Текущий

<?php
$villes = '"paris","fes","rabat"';
?

Изменить на

<?php
$villes = array("paris","fes","rabat");
?>

Теперь попробуйте передать $villes в функцию подготовки и посмотрите, работает ли она. Надеюсь, поможет.

person web-nomad    schedule 17.05.2012
comment
Я уже пробовал, но он передает только первый элемент массива - person mgraph; 17.05.2012