Как правильно подготовить SQL-запрос с оператором %LIKE%?
Я хочу использовать оператор LIKE %text%, при этом используя класс WordPress $wpdb для санитизации и подготовки входных данных.
SELECT column_1 from `prefix_my_table` WHERE column_2 LIKE '%something%';
Я пробовал что-то вроде этого, но безуспешно:
$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %s;", like_escape($number_to_put_in_like));
Как правильно подготовить SQL-запрос с оператором %LIKE%, используя класс базы данных WordPress?
Функция $wpdb->esc_like существует в WordPress потому, что обычное экранирование базы данных не экранирует символы % и _. Это означает, что вы можете добавлять их в свои аргументы для wpdb::prepare() без проблем. Это также то, что я вижу в основном коде WordPress:
$wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%');
Таким образом, ваш код будет выглядеть так:
$wpdb->prepare(
"SELECT
column_1
FROM
`{$wpdb->base_prefix}my_table`
WHERE
column_2 LIKE %s;",
'%' . $wpdb->esc_like($number_to_put_in_like) . '%'
);
Вы также можете добавить %% в свой запрос, чтобы получить буквальный символ % (wpdb::prepare() использует vsprintf() в фоновом режиме, который имеет такой синтаксис), но помните, что ваша строка не будет заключена в кавычки, вам нужно добавить их самостоятельно (что обычно не требуется делать в wpdb::prepare()).
@FranciscoCorralesMorales: Чтобы указать, что всё внутри должно рассматриваться как выражение с переменной, иначе будет виден только $wpdb, а ->prefix после него будет проигнорирован.
Jan Fabry
@JanFabry Близко. Я бы уточнил комментарий: "... иначе будет воспринято всё выражение $wpdb->base_prefixmy_table и будет попытка найти свойство base_prefixmy_table вместо просто base_prefix.
Flimm
Также стоит упомянуть, что символы % заменяются на невероятно длинный хэш. Это действительно выглядит странно, когда вы делаете var_dump SQL-вывода. После нескольких часов поисков удалось выяснить, что это исправление уязвимости SQL-инъекций в WordPress 4.8.3. https://stackoverflow.com/a/57914094/7977916
NME New Media Entertainment
Вам нужно удваивать знаки процента, чтобы они не интерпретировались как маркеры фрагментов в wpdb->prepare():
$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %%%s%%;", $wpdb->esc_like( $number_to_put_in_like));
P.S. Не уверен, что это лучший/единственный способ сделать это.
Помните, что вы должны сами добавить кавычки вокруг строки, потому что wpdb::prepare добавляет их только для %s, перед которым нет символа %. Финальная часть вашего запроса должна выглядеть как WHERE column_2 LIKE '%%%s%%'.
Jan Fabry
Вот один из проверенных способов, который работает:
$search_text = "%" . $_GET['some_text'] . "%";
$user_count = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM mix_library WHERE ml_setting_name LIKE %s",
$search_text
)
);
Замените переменные в соответствии с вашими потребностями.
Вам следует экранировать символы % (используя функцию like_escape()). Подробнее см.: http://codex.wordpress.org/Class_Reference/wpdb#Protect_Queries_Against_SQL_Injection_Attacks
Stephen Harris
$safe_sql = $wpdb->prepare("SELECT * FROM $wp_track_table $sql",["*yoursecretkey*".$_POST['search']."*yoursecretkey*"]);
$safe_sql = str_replace("*yoursecretkey*", "%", $safe_sql);
Я нашел подходящее решение с приведенным выше кодом. Обязательно попробуйте его.
То есть ваш подход заключается в том, чтобы передать случайную строку в prepare(), а затем заменить её на проценты? Это похоже на борьбу с WordPress.
Rup