Почему при чтении кэша get_transient перезаписываются данные в базе?

Рейтинг: 0Ответов: 1Опубликовано: 18.02.2023

На сайте под управлением 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 отрабатывает с ошибкой - поле в бд может очиститься.

Может быть это кому-то пригодится