Является $ wpdb-> подготовкой к побегу? Как правильно использовать его?

Im в значительной степени смущен $ wpdb-> подготовкой. Я хочу использовать его для дезинфекции ввода пользователя, но оказалось, что он уничтожает запрос. Я не могу себе представить, что так оно и должно работать, но я не могу понять, что я делаю неправильно. Пожалуйста, будьте так терпеливы и укажите мне решение. Следующий код является простым примером демонстрационных целей, чтобы просто понять, что происходит не так и как. Позже будет введен пользовательский ввод этого запроса.

Когда я оставил готовить и использовать sprintf, вместо этого этот пример работает:

global $wpdb; $mydb = new \wpdb( "My_Login" ,"My_PW" , "My_Custom_DB" ,"localhost"); //wpdb instance for my custom db $tablename = "books"; $sort_direction = "DESC"; $limit = 5; $sqlquery = sprintf( "SELECT * FROM %s ORDER BY datum %s LIMIT %d", $tablename, $sort_direction, $limit ); $res = $mydb->get_results( $sqlquery ); echo "<br>".$sqlquery."<br>"; var_dump($res); 

Результат var_dump () – это правильный массив, содержащий ожидаемый результат.

Вывод $ sqlquery:

 SELECT * FROM books ORDER BY datum DESC LIMIT 5 

Это правильный SQL.

Теперь я буду использовать prepare (это единственная измененная строка):

 global $wpdb; $mydb = new \wpdb( "My_Login" ,"My_PW" , "My_Custom_DB" ,"localhost"); //wpdb instance for my custom db $tablename = "books"; $sort_direction = "DESC"; $limit = 5; $sqlquery = $mydb->prepare( "SELECT * FROM %s ORDER BY datum %s LIMIT %d", $tablename, $sort_direction, $limit ); $res = $mydb->get_results( $sqlquery ); echo "<br>".$sqlquery."<br>"; var_dump($res); 

Результат var_dump () равен NULL

Вывод $ sqlquery:

 SELECT * FROM 'books' ORDER BY datum 'DESC' LIMIT 5 

Где, очевидно, имя таблицы и DESC не должны быть заключены в кавычки. ИМО – причина, по которой она терпит неудачу. Я дважды проверил, что это не связано с инстанцией $ wpdb. Когда я работаю с $ wpdb, результат экранирования остается неизменным.

Что происходит или что я не так? Пожалуйста, помогите мне.

То, что вы сделали неправильно, состояло в том, чтобы подготовить эти предметы в первую очередь.

Вы можете запускать переменные «данные» через prepare (). Вы не запускаете имена таблиц или маршруты сортировки или лимиты через него. Они являются частью самой команды SQL, они не являются данными, которые относятся к информации, которая хранится в столбце базы данных.

В запросе SELECT нет ввода данных … поэтому у него нет никаких входов, которые могут быть подготовлены.

Для конкретного случая SELECT данные – это материал в предложении WHERE. column =% s и т. д. Это переменная часть данных, которая может быть потенциально опасной, поскольку она, возможно, исходит от ввода пользователем. Чтобы данные были выполнены, подготовьтесь к их безопасности. Но если у вас есть жестко запрограммированный «DESC» для заказа, тогда нет смысла его запускать в процессе подготовки. Это «DESC». Это безопасно, как есть. Только данные, которые вы не знаете, что это такое, могут быть небезопасными.

Изменить: если данные поступают с пользовательского ввода, например, если пользователь может выбрать количество отображаемых элементов, то эти данные должны быть дезинфицированы. Таким образом, лимиты могут выполняться через подготовку, поскольку они являются целыми числами и могут исходить от пользователя, который выбирает «5» или «10».

Однако вы не позволите пользователю напрямую вводить имя таблицы или порядок сортировки. Они будут выбирать направление для отображения вещей, но вы должны преобразовать его в ASC или DESC. Они не выбрали бы «книги» напрямую, но могли бы выбрать из списка, который вы интерпретируете как «книги». Что-то в этом роде.