Использование функций WordPress

t

Ситуация: стандартный запрос убивает скорость

Вы создаёте сайт для локальной сети ресторанов. Клиент хочет вывести на главной странице «Акции недели» — три последних поста из категории «akcii», а в подвале — пять случайных отзывов. Казалось бы, типовые задачи. Но после запуска страница грузится 6–7 секунд. Менеджер жалуется на падение конверсии, а владелец бизнеса просит «просто переустановить WordPress». Знакомая история?

Проблема: разработчик использовал WP_Query в лоб, без фильтрации колонок и без кэширования. Второй цикл выполнял ORDER BY RAND(), что на базе в 5 000 записей давало тяжелый файл сортировки. Третий запрос подтягивал мета-поля каждой записи отдельно. Типичный случай, когда «просто» приводит к катастрофе производительности.

Решение: рефакторинг через параметры и кэш

Мы переписали выборку. Для акций установили posts_per_page = 3 и явно указали fields = 'ids' — так база возвращает только идентификаторы, а не полные объекты. Для отзывов отказались от ORDER BY RAND() в пользу сохранения массива ID в транзитном кэше на час.

Вместо повторных вызовов get_post_meta() в цикле загрузили метаданные одним запросом через update_meta_cache(). Время генерации страницы упало до 1.7 секунд, а после подключения плагина объектного кэширования — до 0.9 секунды. Результат: владелец доволен, бюджет на хостинг не вырос.

Чтобы вы не повторяли чужих ошибок, разберем пять профессиональных приёмов работы с функциями WordPress, которые редко описывают в базовых туториалах.

Неочевидные параметры WP_Query: экономьте память

Самый частый миф: WP_Query всегда возвращает только то, что вы явно попросили. На практике объект по умолчанию подтягивает все поля таблицы wp_posts, мета-данные (update_post_meta_cache) и термы (update_post_term_cache). Если вам нужны только ID или заголовки, вы расходуете ресурсы впустую.

Профессионалы всегда указывают fields => 'ids' или 'id=>parent', когда не собираются вызывать the_post() или setup_postdata(). Для списка новостей на главной или меню достаточно идентификаторов.

Второй момент — сортировка. Никогда не используйте 'orderby' => 'rand' на выборке более 50 записей. Это заставляет MySQL сортировать всю таблицу. Лучше хранить список ID в настройках темы или в транзитном кэше и перемешивать уже готовый массив на PHP.

Hooks: действие vs фильтр — где грань?

Многие путают add_action и add_filter, используя их как взаимозаменяемые. Это приводит к трудноуловимым багам. Action — это событие: «сделай что-то в этот момент» (отправить письмо, записать в лог). Filter — это модификация данных: «измени значение и верни обратно». Фильтр обязан возвращать значение. Экшн — нет.

Профессиональный приём: при создании собственного фильтра всегда передавайте минимум один аргумент — изменяемую переменную. И возвращайте её в конце функции, иначе данные обнулятся. Для экшнов, наоборот, возврат необязателен, но если вы вернёте false — некоторые ядра могут прервать выполнение.

Ещё один нюанс: приоритеты. По умолчанию 10. Если два хука с одинаковым приоритетом — порядок выполнения не гарантирован. Для критичных операций ставьте приоритет 5 (ранний) или 15 (поздний).

  1. Определите цель: меняете данные (filter) или выполняете действие (action).
  2. Используйте apply_filters( 'my_filter', $value, $arg2 ) — всегда передавайте хотя бы один изменяемый параметр.
  3. Для действий используйте do_action( 'my_hook', $data ) без возврата.
  4. В файле functions.php группируйте хуки: сначала фильтры, потом экшны.
  5. Избегайте приоритетов от 0 до 3 — обычно они зарезервированы ядром.
  6. Не вешайте тяжелые SQL-запросы на init — используйте wp_loaded.
  7. Тестируйте хуки с включенным WP_DEBUG — он покажет ошибки при неправильной передаче аргументов.

Сниппеты в functions.php: правильная структура

Файл functions.php часто превращается в помойку из кусков кода с форумов. Профи пишут модульно: каждая группа функций — в отдельный include-файл внутри папки темы. Например, /inc/post-types.php, /inc/shortcodes.php, /inc/performance.php.

Главный файл темы подключает эти части через require_once. Это упрощает отладку и перенос функций между проектами. К тому же, при обновлении темы ваш кастомный код не потеряется, если вы разместили его в отдельном файле внутри дочерней темы.

Нюанс: functions.php загружается при каждой смене темы. Если вы добавили туда объявление кастомного типа записи, при переключении на другую тему этот тип исчезнет, и данные в базе станут «сиротами». Решение для серьёзных проектов — выносить регистрацию типов записей в функциональный плагин (mu-plugin).

Сложные запросы: JOIN и подзапросы без плагинов

Когда стандартный WP_Query не справляется — вам нужен кастомный SQL через $wpdb. Например, вывести товары, у которых цена (мета-поле) больше среднего значения по всей категории. Это простое подзапросное условие, но meta_query такое не поддерживает.

Решение: напишите прямой SQL с помощью $wpdb->prepare() и get_results(). Никогда не используйте query() без подготовленных выражений — это дыра в безопасности. Обязательно проверяйте, что возвращает запрос, с помощью wp_list_pluck().

Важно: результаты кастомного SQL не кэшируются WordPress автоматически. Обёрните вызов в if ( false === ( $results = get_transient( 'my_query' ) ) ) { ... set_transient() }. Время жизни транзиента выбирайте по частоте обновления данных.

  1. Подключите global $wpdb; в начале функции.
  2. Используйте $wpdb->prepare( 'SELECT ID FROM %i WHERE ...', $wpdb->posts )%i для таблиц.
  3. Возвращайте стандартный объект WP_Post или массив ID, чтобы вписаться в архитектуру.
  4. Всегда ставьте лимит записей (LIMIT), иначе сайт упадёт при большом объёме.
  5. Создайте отдельный метод или функцию для сложных запросов — не пишите их прямо в шаблоне.

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

WordPress даёт огромную гибкость, но за каждую непродуманную функцию вы платите скоростью. В 2026 году, когда Core Web Vitals стали обязательным фактором ранжирования, каждый лишний запрос к базе может стоить вам позиций в поиске.

Профессиональный подход — всегда начинать с вопроса: «Могу ли я получить эти данные без SQL?». Если да — используйте wp_cache_get() или опции. Если нет — оптимизируйте WP_Query или пишите кастомный SQL с кэшированием. Регулярно профилируйте страницы с помощью Query Monitor, чтобы видеть узкие места.

И главное: не бойтесь разбираться в ядре. Функции WordPress написаны с умом, и часто внутри них уже есть готовые оптимизации — надо лишь знать их имена. Уделите час изучению WP_Query документации — это окупится десятками сэкономленных часов в будущем.

Добавлено: 24.04.2026