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.
Create blog | Privacy Policy | Terms & Conditions | Contact Us
Rate this post
4 of 5 based on 1847 votesComments