Нужно ли использовать wpdb prepare?

11 мая 2011 г., 10:16:11
Просмотры: 58.6K
Голосов: 38

Я новичок в SQL и хочу узнать, нужно ли использовать wpdb->prepare для следующего запроса к созданной мной таблице

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = "SELECT * FROM " . $tablename . " ORDER BY date_created DESC";
$resulst = $wpdb->get_results( $sql , ARRAY_A );

Нужно ли мне здесь использовать prepare? Как это сделать?

Спасибо

0
Все ответы на вопрос 3
7
47

Рекомендуется всегда использовать prepare, но основное его назначение — защита от SQL-инъекций. Поскольку в вашем примере нет пользовательского ввода или возможности повлиять на запрос, это не является проблемой.

Однако, как уже упоминалось, лучше придерживаться этой практики. Начав использовать prepare, вы вряд ли перестанете. В вашем случае это можно сделать так:

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM %s ORDER BY date_created DESC",$tablename );
$results = $wpdb->get_results( $sql , ARRAY_A );

Подробнее об использовании можно прочитать в кодексе

11 мая 2011 г. 10:43:00
Комментарии

Привет @Bainternet, спасибо за такое четкое объяснение - почему-то, когда я пробую твой код, он возвращает пустой массив. Я проверил и перепроверил на опечатки. Если я выполняю неподготовленный запрос, я получаю массив. Не понимаю, почему это не работает..!

Richard Sweeney Richard Sweeney
11 мая 2011 г. 11:03:09

Странно. Я попробовал использовать тот же код с другим запросом: `$tablename = $wpdb->prefix . "my_custom_table"; $concert_id = 1;

$sql = "SELECT * FROM " . $tablename . " WHERE concert_id = %d LIMIT 1;";

$prep_sql = $wpdb->prepare( $sql, $concert_id );

$get_concerts = $wpdb->get_results( $prep_sql , ARRAY_A );`

И он отлично работает! Не уверен, почему так. Но в любом случае теперь я это понял!

Richard Sweeney Richard Sweeney
11 мая 2011 г. 11:36:02

Заключение названия таблицы в одинарные кавычки не сработает. Обычное экранирование делается с помощью обратных кавычек, поэтому ваш запрос должен выглядеть так: SELECT * FROM \wp_my_custom_table`. Вы можете включить поддержку двойных кавычек, но тогда это должно выглядеть так:SELECT * FROM "wp_my_custom_table"`.

Jan Fabry Jan Fabry
11 мая 2011 г. 11:52:17

Я не согласен с этим ответом. Зачем экранировать, если функция уже экранирует всё? Вы думаете, WordPress решит убрать экранирование из ядра? Также нет смысла экранировать имя таблицы :) потому что оно жёстко задано и вы знаете, что оно корректно. Я понимаю, что это просто пример, но всё же не экранируйте имена таблиц - у меня были проблемы при использовании prepare с именами таблиц, он добавляет обратные кавычки, и SQL выдаёт ошибку.

Tommixoft Tommixoft
4 нояб. 2014 г. 14:41:44

@Tommixoft Если вы перечитаете ответ, то увидите, что вы фактически говорите то же самое, что и я, и что имя таблицы приведено как пример.

Bainternet Bainternet
5 нояб. 2014 г. 09:07:36

Можете ли вы подтвердить утверждение, что это лучшая практика? Кажется странным (в смысле - не лучшей практикой) использовать функцию, которая в данном случае не нужна и ожидает 2+ параметра...

random_user_name random_user_name
14 окт. 2016 г. 17:23:32

Ааа, ответ из 2011 года!!! Если вы принимаете ввод от пользователя в запрос, то да, это всегда лучшая практика.

Bainternet Bainternet
20 окт. 2016 г. 17:27:15
Показать остальные 2 комментариев
2

При использовании prepare ваш код защищается от уязвимостей SQL-инъекций.

Вот код, который вам нужно изменить для использования prepare():

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM {$tablename} ORDER BY date_created DESC");
$resulst = $wpdb->get_results( $sql , ARRAY_A );
12 окт. 2015 г. 18:34:35
Комментарии

Просто использование prepare() не означает, что код автоматически защищен от SQL-инъекций. Ваш код может создавать впечатление, что $tablename защищен от SQL-инъекций, поскольку используется в prepare, но это не так, потому что он не передается через аргументы. В данном случае это не проблема, так как содержимое $tablename безопасно, но, думаю, было бы полезно это прояснить.

Constantin Constantin
28 дек. 2020 г. 17:04:58

Да. Этот ответ неверен и, я бы сказал, опасно вводит в заблуждение. Вы вызвали prepare таким образом, который на самом деле не защищает от SQL-инъекций.

Harry Wood Harry Wood
11 нояб. 2021 г. 13:30:10
0

В вашем случае SQL-инъекция невозможна. Ваш код не требует дополнительной защиты, так как не использует пользовательский ввод, такой как: post, get, request, cookie.

Не используйте сложные функции без необходимости, чтобы сэкономить ресурсы сервера.

17 июл. 2015 г. 11:51:54