You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WooCommerce中重新生成产品/变体对象的原生瞬态数据?

How to Update WooCommerce Price Transients via Cron Using read_price_data()

Got it, let's tackle this problem step by step. You're already using the correct hooks to modify variation and variable product prices, but the key fix for your performance issue is updating those wc_prices_{id} transients programmatically—specifically via a cron job. The read_price_data() method you found is exactly what we need, and calling it in a cron script is straightforward once you understand WooCommerce's data store system.

Step 1: Understand What read_price_data() Does

First, a quick recap: The read_price_data() method in WC_Product_Variable_Data_Store_CPT (and its variation counterpart) generates and caches the transient data WooCommerce uses to display price ranges for variable products and individual variation prices. When you update your custom prices, these transients don't automatically refresh—so calling this method forces WooCommerce to rebuild them with your new custom prices.

Step 2: Write a Function to Update Transients for a Single Variable Product

Here's a reusable function that targets a specific variable product, validates it, and calls read_price_data() to refresh its transients:

function update_variable_product_price_transients( $product_id ) {
    // Ensure WooCommerce is loaded before proceeding
    if ( ! class_exists( 'WC_Product' ) || ! class_exists( 'WC_Data_Store' ) ) {
        return;
    }

    // Fetch the product object
    $product = wc_get_product( $product_id );

    // Validate we're working with a valid variable product
    if ( ! $product || ! $product->is_type( 'variable' ) ) {
        error_log( "Failed to update transients: Product ID {$product_id} is not a valid variable product." );
        return;
    }

    try {
        // Load the variable product data store instance (WooCommerce's recommended way)
        $data_store = WC_Data_Store::load( 'product-variable' );

        // Call read_price_data() to rebuild and cache the price transients
        $data_store->read_price_data( $product );

        error_log( "Successfully updated price transients for product ID {$product_id}." );
    } catch ( Exception $e ) {
        error_log( "Error updating transients for product ID {$product_id}: " . $e->getMessage() );
    }
}

Step 3: Add a Cron Job to Trigger the Function

You have two options here: trigger updates on product save (for real-time refreshes when prices change) or schedule a recurring cron job to bulk-update products.

Option A: Trigger on Product Save (Instant Refresh)

Add this hook to automatically update transients whenever a variable product is saved:

function trigger_transient_update_on_product_save( $post_id, $post, $update ) {
    // Skip autosaves and revisions
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if ( wp_is_post_revision( $post_id ) ) return;

    // Only target published variable products
    if ( 'product' === $post->post_type ) {
        $product = wc_get_product( $post_id );
        if ( $product && $product->is_type( 'variable' ) ) {
            update_variable_product_price_transients( $post_id );
            
            // Optional: Update transients for all child variations too
            foreach ( $product->get_available_variations() as $variation ) {
                update_variation_price_transients( $variation['variation_id'] );
            }
        }
    }
}
add_action( 'save_post_product', 'trigger_transient_update_on_product_save', 10, 3 );

Option B: Recurring Bulk Cron Job

If you need to update all variable products on a schedule (e.g., daily), use this:

function update_all_variable_product_transients() {
    // Query all published variable products
    $args = array(
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'tax_query'      => array(
            array(
                'taxonomy' => 'product_type',
                'field'    => 'slug',
                'terms'    => 'variable',
            ),
        ),
    );

    $variable_products = get_posts( $args );

    foreach ( $variable_products as $product_post ) {
        update_variable_product_price_transients( $product_post->ID );
    }
}

// Schedule the cron job to run daily (adjust the schedule as needed)
function schedule_bulk_transient_update() {
    if ( ! wp_next_scheduled( 'bulk_variable_price_transient_update' ) ) {
        wp_schedule_event( time(), 'daily', 'bulk_variable_price_transient_update' );
    }
}
add_action( 'wp', 'schedule_bulk_transient_update' );
add_action( 'bulk_variable_price_transient_update', 'update_all_variable_product_transients' );

Step 4: Handle Individual Variation Transients (Optional)

If your custom price logic also modifies individual variation prices, you'll want to refresh their wc_var_prices_{variation_id} transients too. Use this function:

function update_variation_price_transients( $variation_id ) {
    if ( ! class_exists( 'WC_Product' ) || ! class_exists( 'WC_Data_Store' ) ) {
        return;
    }

    $variation = wc_get_product( $variation_id );

    if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
        error_log( "Failed to update transients: Variation ID {$variation_id} is not valid." );
        return;
    }

    try {
        $data_store = WC_Data_Store::load( 'product-variation' );
        $data_store->read_price_data( $variation );
        
        error_log( "Updated price transients for variation ID {$variation_id}." );
    } catch ( Exception $e ) {
        error_log( "Error updating variation transients: " . $e->getMessage() );
    }
}

Key Notes

  • Always use WooCommerce's data store factory: Directly instantiating WC_Product_Variable_Data_Store_CPT isn't recommended—WC_Data_Store::load() ensures you're using the active data store (which could be overridden by extensions).
  • Error logging: The error logs help debug if something fails (check your WordPress debug log or server error logs).
  • Performance: For bulk updates, consider adding a delay between product processing if you have hundreds of products, to avoid overwhelming your server.

内容的提问来源于stack exchange,提问作者Alexandre Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:37:31