Нужно ли использовать wpdb prepare?
Я новичок в 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
? Как это сделать?
Спасибо

Рекомендуется всегда использовать 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 );
Подробнее об использовании можно прочитать в кодексе

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

Странно. Я попробовал использовать тот же код с другим запросом: `$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 );`
И он отлично работает! Не уверен, почему так. Но в любом случае теперь я это понял!

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

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

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

Можете ли вы подтвердить утверждение, что это лучшая практика? Кажется странным (в смысле - не лучшей практикой) использовать функцию, которая в данном случае не нужна и ожидает 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 );

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

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