John Davidson

php - WP Product Query that updates custom meta reached the memory limit

0 comments
Message:


The server has a memory limit of about 2000mb. That's pretty high, so I'm not sure if simply increasing that limit is the answer or not.


The script uses get_posts to iterate through all 100,000+ products, get_the_terms to get an attribute, and the biggest one is update_post_meta to update the meta field.


The main reason for the script is to assign a custom meta "priority_brand" to products based on the order set using an Advanced Custom Fields repeater. That way, someone can drag & drop a priority by brand order, and then on the front end I modify the query elsewhere to display those products based on that priority order.


The following script runs as a CRON:




<?php
include '/path/to/wp-load.php';

echo "brand-priority";
error_log("brand-priority");


$brands = get_field("brands_order", "options");
$brand_IDs = array();
foreach ($brands as $brand) {
array_push($brand_IDs, $brand['brand']);
}

$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'fields' => 'ids',
);
$products = get_posts($args);

$i = 1; foreach ($products as $ID) {
$brand = get_the_terms($ID, 'pa_brand');
$brand = $brand[0] ?? false;
if (!$brand) {
continue;
}

$brand_ID = $brand->term_id;
$priority = array_search($brand_ID, $brand_IDs) + 1;

update_post_meta($ID, "priority_brand", $priority);
}


My Answer:
To optimize the script and prevent reaching the memory limit, you can try the following approaches:

1. Batch Processing: Instead of updating all products in a single loop, you can process them in smaller batches. This can help reduce the memory usage and prevent hitting the memory limit. Here's an example of how you can implement batch processing:

php
$batch_size = 100; // Number of products to process in each batch
$total_products = count($products);
$offset = 0;

while ($offset < $total_products) {
$batch_products = array_slice($products, $offset, $batch_size);

foreach ($batch_products as $ID) {
// Your update_post_meta logic here
}

$offset += $batch_size;
}


2. Use WP_Query: Instead of using get_posts, you can use WP_Query with a custom query to fetch and update the products. WP_Query is more memory-efficient compared to get_posts. Here's an example:

php
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'fields' => 'ids',
);

$query = new WP_Query($args);

if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$ID = get_the_ID();

// Your update_post_meta logic here
}

wp_reset_postdata();
}


3. Optimize Database Queries: Make sure that your database queries are optimized and efficient. Avoid unnecessary queries and make use of caching where possible to reduce the load on the server.

4. Increase PHP Memory Limit: If none of the above solutions work, you can try increasing the PHP memory limit in your php.ini file or using ini_set('memory_limit', '256M'); at the beginning of your script. However, this should be considered as a last resort and not a permanent solution.

By implementing these optimizations, you should be able to prevent hitting the memory limit and improve the performance of your WP Product Query script.

Rate this post

4 of 5 based on 1847 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us