Как сформировать безопасный запрос к базе WordPress?

Ссылка скопирована
1 ответ

Есть 3 кастомных типа записи, как сформировать безопасный поиск по ним?
Передается через AJAX на сервер часть заголовка, нужно найти подходящие записи?

Основа SQL запроса – LIKE

SELECT * FROM posts WHERE title LIKE %слово_из_запроса%

SELECT * FROM posts WHERE title LIKE %слово_из_запроса%

Названия кастомных записей подставлю сам))

Дополнительно:

Как сформировать безопасный запрос к базе WordPress?

$args = array( 	'posts_per_page' => -1, 	'post_type'      => array( 'post', 'page', 'movie', 'book' ), 	's'              => 'search phrase', );  $query = new WP_Query( $args );

$args = array( 'posts_per_page' => -1, 'post_type' => array( 'post', 'page', 'movie', 'book' ), 's' => 'search phrase', ); $query = new WP_Query( $args );

  • Как искать записи только по заголовку?
    SQL — post_title LIKE %s%
  • Илья Петров, попробуйте эти решения https://stackoverflow.com/questions/62350261/how-t...
  • Артем Золин, спасибо, использовал это решение)

    Полный код выложил тут
    https://qna.habr.com/q/1290594

Ответы:

См. wp_query

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Сергей Миронов Ответ

Для WordPress безопаснее начинать не с ручного SELECT к таблице posts, а с WP_Query. Он уже учитывает типы записей, статусы, ограничения выборки и корректно работает с внутренними таблицами WordPress. В вашем случае можно передать массив нужных post_type, ограничить post_status значением publish и поставить разумный posts_per_page. Переданную из AJAX строку обязательно нужно очистить: убрать слэши, привести к обычному тексту, обрезать длину и не выполнять поиск по пустой строке.

Важный момент: стандартный параметр s ищет не только по заголовку. В зависимости от версии WordPress и настроек он может затрагивать контент и отрывок записи. Если нужно искать строго по post_title, используйте отдельный параметр запроса и фильтр posts_where, где добавляется условие по заголовку. Внутри такого фильтра нельзя склеивать SQL со строкой пользователя напрямую. Для LIKE сначала применяется esc_like, затем к значению добавляются проценты, после этого условие подставляется через prepare.

Минимальная безопасная схема для AJAX такая:

  • проверить nonce, чтобы обработчик нельзя было дергать с чужих страниц без контроля;
  • получить строку поиска из POST или GET и очистить её штатными функциями WordPress;
  • ограничить минимальную и максимальную длину, например не искать по одному символу и не принимать огромные строки;
  • жёстко задать разрешённые post_type на сервере, а не доверять списку типов, пришедшему от клиента;
  • искать только среди нужных post_status, чаще всего publish;
  • возвращать в JSON только нужные поля: ID, title, permalink, возможно тип записи, но не полный объект записи;
  • после нестандартного фильтра снять его, чтобы он не повлиял на другие запросы на этой же загрузке WordPress.

Прямой SQL через wpdb имеет смысл только если WP_Query действительно не подходит. Даже тогда нельзя писать title LIKE %строка% обычной конкатенацией. Правильный порядок такой: исходную строку очистить, подготовить LIKE через esc_like, затем использовать prepare. Для списка post_type тоже лучше не подставлять пользовательский ввод, а сформировать список из заранее разрешённых значений.

Также не используйте SELECT * для автодополнения. Это лишняя нагрузка и риск случайно отдать ненужные данные. Для подсказок обычно достаточно ID и post_title, а ссылку можно получить отдельной функцией WordPress. Если поиск вызывается при вводе каждой буквы, добавьте debounce на клиенте и лимит результатов на сервере. Так запрос будет безопаснее, быстрее и не превратится в источник нагрузки на базу.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно