wpdb не выполняет запрос с использованием оператора IN после привязки массива к заполнителю

#mysql #sql #wordpress

#mysql — сервер #sql #wordpress (wordpress ) #mysql #wordpress

Вопрос:

У меня есть этот запрос:

 $post_query = "SELECT * 
FROM wpps_terms t
INNER JOIN wpps_term_taxonomy tt ON tt.term_id = t.term_id AND t.term_id IN ($placeholder)
WHERE tt.taxonomy = 'property-area' AND t.name LIKE '%s' ";
  

которые используют IN оператор, я связываю значения следующим образом:

 $taxonomiesArr = [4, 8];

$filter = array_map(function($v) {
    return "'" . esc_sql($v) . "'";
}, $taxonomiesArr);
$filter = implode(',', $filter);

$placeholder = implode(',', array_fill(0, count($filter), '%s'));
  

Я пытаюсь связать taxonomiesArr вот так:

 $like = '%' . $wpdb->esc_like('columbia') . '%';
$result = $wpdb->get_results($wpdb->prepare($post_query, $taxonomiesArr, $like));
  

проблема в том, что запрос никогда не выполняется и wpdb->print_error() ничего не показывает. Я уверен, что запрос не выполнен, потому что, если я посмотрю wpdb->last_query , я получу выполнение предыдущего запроса.

Если я изменю подготовку как:

 $result = $wpdb->get_results($wpdb->prepare($post_query, 4, 8, $like)); 
  

запрос выполнен, но почему я получаю такое поведение? Я не могу передать значения вручную!

Ответ №1:

Эти 2 строки кода вызывают проблему:

 $filter = implode(',', $filter);
$placeholder = implode(',', array_fill(0, count($filter), '%s'));
  

Вы преобразуете $filter в строку перед использованием ее в count — вы, вероятно, получаете следующее предупреждение в своих журналах: «Предупреждение: count(): параметр должен быть массивом или объектом, который реализует счетность в …«

Это означает, что array_fill функция не работает, и ваша $placeholder строка неверна

Как это исправить:

Либо переместите implode строку фильтра ниже кода, в котором вы настраиваете свой $placeholder , либо сохраните count часть массива в переменную, прежде чем вы ее взорвете, и используйте ее вместо count:

 $taxonomiesArr = [4, 8];

$filter = array_map(function($v) {
    return "'" . esc_sql($v) . "'";
}, $taxonomiesArr);

/* MOVE THIS LINE (or save count($filter) into a var before it)
   - it converts the array to string but you need an array for count in array_fill */
// $filter = implode(',', $filter);

$placeholder = implode(',', array_fill(0, count($filter), '%s'));

$filter = implode(',', $filter);
  

Если вы print_r($placeholder); в конце приведенного выше кода получите %s,%s ожидаемый результат