Я пытаюсь использовать WP Redis для кэширования всего объекта $ wp_query с ключом $ query_vars_hash .
Вот как $wp_query
было добавлено $wp_object_cache
:
add_action('wp', function($wp)
{
if ( is_admin() ) return;
global $wp_query;
if ( !wp_cache_get($wp_query->query_vars_hash, 'globals') )
{
wp_cache_add($wp_query->query_vars_hash, $wp_query, 'globals');
}
});
Затем мне нужно проверить, кэшировался ли уже запрос, прежде чем WP_Query
можно будет получать сообщения:
add_action('pre_get_posts', function($query)
{
if ( is_admin() ) return;
$cached_query = wp_cache_get($query->query_vars_hash, 'globals');
if ($cached_query)
{
$GLOBALS['wp_query'] = &$cached_query;
return; // Return immediately to prevent retrieving posts again.
}
});
Проблема :
return
или exit
не работает в этом случае. Затем WP_Query
все равно ударит базу данных, чтобы получить сообщения снова.
Вопрос :
Независимо от плагина, возможно ли полностью прекратить WP_Query
получение сообщений?
return
возможно, это единственная команда, которую мы можем вызвать в этом случае.Ответы:
На данный момент это невозможно.
Когда
'pre_get_posts'
запускается, уже слишком поздно останавливатьсяWP_Query
для выполнения запроса.Сам WordPress, когда вы пытаетесь запросить таксономию, которая не существует, добавляет
AND (0 = 1)
кWHERE
предложению SQL-запроса, чтобы убедиться, что он очень быстро не возвращает результатов ...Там есть билет ПРОФ с патчем , который, вероятно , приземляется в ядре с WP 4.6, который вводит новый фильтр
'posts_pre_query'
. Возвращение массива в этом фильтре приведет кWP_Query
остановке обработки и использованию предоставленного массива в качестве массива сообщений.Это может как-то помочь вам в реализации того, что вы пытаетесь сделать.
Ожидание фота это все, что вы могли бы сделать , это как - то хак , то трюк ядро сам по себе использует довольно хак , а также.
Недавно я начал использовать трюк, когда я хочу остановить WordPress, чтобы делать вещи, которые я не могу остановить чистым способом: я выбрасываю исключение и ловлю его, чтобы продолжить выполнение приложения.
Я покажу вам пример. Обратите внимание, что весь код здесь полностью не проверен.
Прежде всего, давайте напишем пользовательское исключение:
Исключение предназначено для работы в качестве своего рода DTO для транспортировки объекта запроса, так что в
catch
блоке вы можете получить и использовать его.Лучше объяснить с помощью кода:
Это должно более или менее работать, однако, есть много хуков, которые вы не собираетесь использовать, например,
"the_posts"
и многое другое ... если у вас есть код, который использует один из этих хуков для запуска, он сломается.Вы можете использовать эту
cached_query_set
функцию для запуска некоторых хуков, которые могут потребоваться вашей теме / плагинам.источник
do_action
должен быть вtry
блоке.Это вопрос PHP больше, чем вопрос WordPress.
Как прокомментировал @Mark :
Это правда. Размещение
return
в функции означает выход из функции, а размещение возврата в PHP-файле означает выход из файла. Не путайте конструкцию PHPexit()
: P (вы можете найти лучший ответ на SO о PHPreturn
).И ответить на ваш вопрос
Вы можете уменьшить нагрузку на запрос, выбрав один столбец вместо полной таблицы. Как @birgire сделал здесь Удалить запрос главной страницы
Может быть, лучший ответ еще впереди. Я просто поделился тем, что знаю :)
источник
posts_request
фильтр? При таком подходе «+ один столбец» мы выходимWP_Query
раньше, чем при использованииposts_pre_query
фильтра. Также следите за липкими сообщениями,posts_pre_query
но мы можем удалить их,$q->set( 'ignore_sticky_posts', 1 );
например, в примере здесь .posts_pre_query
это не помогает. Ваше решение пока лучшее. :) Если вы знаете, как мы можем выйти из запроса сразу жеpre_get_posts
, это было бы здорово. Спасибо!posts_pre_query
будет доступен с 4.6;)WP_Query
класс с помощью пользовательскогоget_posts()
метода с возможным ранним существованием, который вызываетparent::get_posts()
и пытается переопределить соответствующий запрос. Но я не знаю, будет ли это работать или иметь смысл в вашем случае ;-) @DanЭто станет возможным в 4.6 (при условии отсутствия изменений до выпуска) с новым
posts_pre_query
фильтром https://core.trac.wordpress.org/ticket/36687источник
Да, это возможно в зависимости от того, что вы хотите кешировать. Я сделал аналогичную вещь, чтобы кэшировать основной цикл на нашей домашней странице. По сути, вы можете использовать
posts_request
иposts_results
для перехвата запроса и попадания в кеш, а затем также использоватьfound_posts
для исправления нумерации страниц.Действительно грубый пример взят из нашего кода (не проверено), но вы должны помочь вам понять:
Подробнее здесь: https://www.reddit.com/r/Wordpress/comments/19crcn/best_practice_for_hijacking_main_loop_and_caching/
источник