Ускорение работы WordPress: кэширование произвольных запросов с помощью Transient API

Дата публикации:Март 9, 2012

Использует ли ваша тема WordPress произвольные запросы для отображения случайных, популярных или свежих записей? Если да, то вы должны рассмотреть применение Transient API для кэширования запросов, что позволяет снизить потребление ресурсов, и тем самым сократить время загрузки. Допустим, на вашем сайте в цикле выводится шесть случайных записей. Вывод осуществляется в сайдбар. В данном случае Transient API может оказаться полезным. Каждый раз, когда пользователь обновляет страницу, произвольный запрос WP Query обращается к базе данных и «вытягивает» из нее шесть случайных записей. Если сайт не слишком большой, то это не так страшно. Однако если посетителей действительно много, своими запросами они могут привести к сбою SQL сервера, вследствие которого на экран будет выведено сообщение “Error Establishing Database Connection”. С помощью добавления нескольких строчек кода вы сможете легко восстановить результаты запроса (кэшировать их) в течение определенного периода времени, что осуществляется через Transient API.

Следующий код отвечает за получение случайных записей в цикле:

<?php $random_query = new WP_Query('orderby=rand&posts_per_page=6');
while ($random_query->have_posts()) : $random_query->the_post();
?>
<div class="gridcontainer">
<div class="gridthumb"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?></a></div>
<div class="gridcontent">
<div class="gridtext"><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></div>
</div>
</div>
<?php endwhile; ?>

Таким образом, у нас на выходе всегда был новый контент. Но ведь кэширование запросов, установленное на 12 часов, означало бы, что мы в течение этого временного отрезка получали бы на выход те же самые шесть записей! Чтобы справиться с этим, нам понадобилось прибегнуть к одному интересному решению, которое было найдено Константином Ковшениным. Вместо WP_Query он предложил использовать get_posts для 20 случайных записей. Затем при помощи кэширования результатов этого запроса с помощью Transient API и использования функции array_rand() мы смогли бы отобразить 6 случайных записей из 20 полученных. Тем самым мы смогли бы имитировать эффект случайного выбора записей на своем сайте.

Первое, что нам понадобится сделать, — это установить transient. Воспользуемся примером из кодекса:

// Get any existing copy of our transient data
if ( false === ( $special_query_results = get_transient( 'special_query_results' ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
	$randargs = array('orderby' => 'rand', 'numberposts' => 20);
	$special_query_results = get_posts($randargs);
    set_transient( 'special_query_results', $special_query_results, 60*60*12 );
}

Обратите внимание, что 60*60*12 — это область, в которой вы можете управлять длиной кэша. Не бойтесь экспериментировать с этим значением. Теперь, если мы выведем на экран $special_query_results в цикле foreach, то мы увидим все 20 записей. Таким образом, нам понадобится функция array_rand() для выбора 6 случайных пунктов. Делается это с помощью кода:

$randomposts = get_transient( 'special_query_results' );
$randkey = array_rand( $randomposts, 6 );

Теперь мы сможем получить шесть идентификаторов записей случайным образом. Однако на данном этапе мы не получим значения для каждой записи. Для этого нам понадобится добавить следующий код:

$sixposts[0] = $randomposts[$randkey[0]];
$sixposts[1] = $randomposts[$randkey[1]];
$sixposts[2] = $randomposts[$randkey[2]];
$sixposts[3] = $randomposts[$randkey[3]];
$sixposts[4] = $randomposts[$randkey[4]];
$sixposts[5] = $randomposts[$randkey[5]];

Мы создали массив для $sixposts, в котором мы присваиваем значение каждому из пунктов. Не думаю, что это лучший способ, но он работает. Если у вас есть другие предложения, то оставляйте их в комментариях. Теперь мы можем вывести на экран результат выполнения цикла:

global $post; //required for it to work
foreach( $sixposts as $post ) :  setup_postdata($post);

//All the items go here.

endforeach;  

setup_postdata позволяет вам использовать все тэги цикла, такие как the_permalink, за пределами foreach.

Итоговый результат:

<?php
// Get any existing copy of our transient data
if ( false === ( $special_query_results = get_transient( 'special_query_results' ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
	$randargs = array('orderby' => 'rand', 'numberposts' => 20);
	$special_query_results = get_posts($randargs);
    set_transient( 'special_query_results', $special_query_results, 60*60*12 );
}

// Use the data like you would have normally...
$randomposts = get_transient( 'special_query_results' );
$randkey = array_rand( $randomposts, 6 );
$sixposts[0] = $randomposts[$randkey[0]];
$sixposts[1] = $randomposts[$randkey[1]];
$sixposts[2] = $randomposts[$randkey[2]];
$sixposts[3] = $randomposts[$randkey[3]];
$sixposts[4] = $randomposts[$randkey[4]];
$sixposts[5] = $randomposts[$randkey[5]];

global $post;
foreach( $sixposts as $post ) :  setup_postdata($post); ?>

<div class="gridcontainer">
<div class="gridthumb"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?></a></div>
<div class="gridcontent">
<div class="gridtext"><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></div>
</div>
</div>

<?php endforeach; ?>

В итоге вы делаете запрос к базе данных один раз в 12 часов, вне зависимости от того, сколько пользователей посещает вас сайт в сутки.

Поделиться

Один комментарий

  1. collaps says:

    Скрипт наверное сделан самостоятельно, или же это разработка компании ?

Оставить комментарий

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

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.