Почему при чтении кэша get_transient перезаписываются данные в базе?
На сайте под управлением wordpress есть большое количество статей с иерархическими категориями Страна->Город->Район.
Занимаясь оптимизацией загрузки, я хочу упаковать самую верхнюю родительскую категорию Страна (порядка 250 разновидностей) в метаполе поста parent_countries, задействую для этой операции кэширование в transients.
Для этих целей запускаю последовательно 2 хука: первым add_action('init', 'save_countries') для кеширования категорий, затем комментирую первый и запускаю второй add_action('init', 'save_post_action_update') для непосредственно записи в метатеги постов.
Перед сохранением в set_transient убеждаюсь, что массив собрался верный, в базе данных записался сериализованный массив, вроде бы всё хорошо. Но, при попытке его прочесть get_transient во втором хуке - получаю уже пустую строку и базе данных поле полностью затирается.. Почему?
(Результат в базе после первого хука, set_transient возвращает 1)
1.Проделывал процедуру не один раз - получаю ровно один и тот же результат.
2.В качестве примера: объект $posts_array с аналогичной длиной, как у ассоциативного массива записывается и считывается без проблем, всё четко, т.е. это не из-за кривизны wp или mysql.
3.Пробую решать сохраняя страны в transient, т.к. если пробовать напрямую, то память не выдерживает нагрузки сколько бы её не увеличивал.
add_action('init', 'save_countries');
function save_countries()
{
if ( false === ( $posts_array = get_transient( 'parent_countries' ) ) ) {
$countries = array();
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish'
);
$posts_array = new WP_Query( $args );
}
foreach($posts_array->posts as $post_array)
{
$countries[$post_array->ID] = get_cat_name(get_the_category($post_array->ID)[0]->parent);
}
print_r($countries); // array([1] => "USA", [2] => "UK",..);
set_transient( 'parent_countries', $countries, DAY_IN_SECONDS );
wp_reset_postdata();
}
add_action('init', 'save_post_action_update');
function save_post_action_update()
{
if ( false === ( $posts_array = get_transient( 'posts_array' ) ) ) {
global $post;
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish'
);
$posts_array = new WP_Query( $args );
set_transient( 'posts_array', $posts_array, DAY_IN_SECONDS );
wp_reset_postdata();
}
$countries = array();
if ( false !== ( $countries = get_transient( 'parent_countries' ) ) ) {
var_dump($countries); //string ""
foreach($posts_array->posts as $post_array)
{
if( is_array($countries) && count( $countries ) ){
echo '<p>Update'.$countries[$post_array->ID].'</p>';
update_post_meta($post_array->ID, 'yacht_country', $countries[$post_array->ID]);
}
}
}
}
Ответы (1 шт):
Код рабочий, ничего в нём не менял.
Рассказываю лайфхак: хук init отрабатывает при загрузке страницы и если в предыдущие разы я тестировал на полноценной контентной странице на которые размещены изображения, загружены шрифты, вызваны запросы, то в крайний раз открыл исходный код страницы в html и обновил в адресной строке.
В результате страница подзависла, в процессе отобразилась 500 ошибка, но через некоторое время все же загрузилась и отработал var_dump($countries); во втором хуке init, а с ним и соответствующие метаполя пополнились записями.
(transient в базе сохранился в прежнем виде)
Получается, что нагрузку не вывозил толи хостинг, толи браузер - не знаю.. Но, самое главное, что всё отработало.
Для себя отметил: когда get_transient отрабатывает с ошибкой - поле в бд может очиститься.
Может быть это кому-то пригодится