PHP
#php#wordpress#wp-query#named-arguments#php-8

WordPress: обёртка над WP_Query с именованными аргументами (PHP 8.0)

Функция-обёртка над WP_Query с именованными аргументами для читаемого вызова и устранения путаницы порядка параметров.

Как использовать

  1. Вызывать build_wp_query() с именованными аргументами: limit, post_type, paged, no_found_rows. Порядок не важен.
  2. Требуется PHP 8.0+ (named arguments). Имена параметров соответствуют ключам массива аргументов WP_Query.
  3. Расширять обёртку: добавлять параметры функции и маппинг в массив для WP_Query по документации WordPress.

В WordPress запросы постов делаются через WP_Query: аргументы передаются массивом, порядок ключей не фиксирован, но при вызове своей функции с позиционными параметрами легко перепутать лимит и страницу. Проблема: читаемость и устойчивость к смене порядка — чтобы было явно «12 постов, страница 2», а не «что за 12 и 2». Симптомы: баги из-за переставленных аргументов, необходимость заглядывать в сигнатуру при каждом вызове. Ниже — обёртка над WP_Query с именованными аргументами (PHP 8.0+), соответствующая документации WP_Query; проверка и ограничения.

Решение

Обёртка над WP_Query с именованными аргументами: порядок вызова не важен, сразу видно назначение каждого значения.

<?php

/**
 * Построить WP_Query с именованными аргументами.
 * Параметры соответствуют ключам массива аргументов WP_Query.
 */
function build_wp_query(
    int $limit = 10,
    string $post_type = 'post',
    int $paged = 1,
    bool $no_found_rows = true,
): WP_Query {
    return new WP_Query([
        'post_type'      => $post_type,
        'posts_per_page' => $limit,
        'paged'          => $paged,
        'no_found_rows'  => $no_found_rows,
    ]);
}

Примеры вызова:

// Читаемо: 12 — лимит, 2 — страница, product — тип
$query = build_wp_query(limit: 12, post_type: 'product', paged: 2);

// Часть аргументов опущена — используются значения по умолчанию
$latest = build_wp_query(limit: 5);

// Порядок не важен
$q = build_wp_query(paged: 2, limit: 12);

Именованные аргументы — фича PHP 8.0. Имена параметров совпадают с ключами массива аргументов WP_Query. Для дополнительных параметров (meta_key, orderby, tax_query и т.д.) добавьте параметры в функцию и маппинг в массив внутри неё по официальной документации WP_Query.

Проверка

  1. Версия PHP — на сервере и локально должна быть PHP 8.0+. Иначе синтаксис именованных аргументов вызовет ошибку. Проверка: php -v.

  2. Результат запроса — после вызова используйте объект как обычно:

    $query = build_wp_query(limit: 3, post_type: 'post');
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            // вывод
        }
        wp_reset_postdata();
    }

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

  3. Пагинация — при paged: 2 и достаточном количестве постов в цикле должны быть посты второй страницы. Проверьте, что posts_per_page и paged в сгенерированном WP_Query соответствуют ожиданиям (при необходимости выведите $query->query для отладки).

Типичные ошибки

  • PHP ниже 8.0 — именованные аргументы недоступны. Либо обновите PHP, либо передавайте в обёртку один массив аргументов и передавайте его в new WP_Query($args).
  • Несовпадение имён с WP_Query — имена параметров функции должны соответствовать ключам массива аргументов WP_Query (posts_per_page, paged, post_type и т.д.). Иначе маппинг в массиве будет неверным.
  • Передача лишних ключей — если расширяете обёртку, добавляйте только документированные параметры WP_Query. Неизвестные ключи могут игнорироваться или давать неожиданное поведение.
  • no_found_rows — для пагинации без подсчёта общего числа страниц ставьте no_found_rows: true (как в примере), чтобы не выполнять лишний COUNT-запрос. Для вывода «всего страниц» может понадобиться false и использование $query->max_num_pages.

Где применять

  • Темы и плагины WordPress: читаемые вызовы запросов постов в шаблонах, виджетах, шорткодах. Продакшн и dev при PHP 8.0+.
  • Расширение обёртки: при необходимости добавьте параметры (orderby, order, meta_key, tax_query и т.д.) и прокидывайте их в массив аргументов WP_Query по документации.

Связанные сниппеты: match по статусу заказа (режим запроса) (другой контекст запросов), PHP 8.3 override-атрибут (современный PHP).