WooCommerce JSON文件导入插件内存超限与执行超时问题求解
问题核心原因
你的代码存在2个严重的效率问题,是导致超时和内存溢出的核心诱因:
- 循环逻辑错误:你将商品入库的
foreach ($products as $key => $product)写在了遍历商品源数据的foreach ($articoli as $key => $articolo)循环内部,相当于每新增1个商品到待处理数组,就会把之前所有已经处理过的商品全部重复执行一次插入/更新操作。600个商品会产生36万次重复的数据库写入请求,时间复杂度达到O(n²)。 - 价格匹配效率低:每次匹配商品价格都遍历完整的价格数组,没有提前构建索引,额外增加了大量无意义的循环操作。
优化方案
1. 修复基础逻辑
先完成所有商品数据的组装,再统一执行入库操作,把嵌套循环改成两个独立的平级循环。
2. 提前构建价格索引
把价格数组按商品ID提前转为哈希表,价格匹配从O(n)降为O(1)。
3. 增加内存释放机制
每处理固定数量的商品就清理WordPress对象缓存,避免内存持续累积占用。
4. 优化定时任务执行
如果还是存在超时问题,可将WordPress自带的Cron替换为服务器系统级crontab直接触发脚本,或者把导入任务拆分为多个小批次,每批次处理50个商品,处理完成后自动调度下一批次任务。
优化后参考代码
public function process_products(){ $file_path = ABSPATH . '/data/import/data.json'; if (!file_exists($file_path)) { return; } $data = file_get_contents($file_path); $json_data = json_decode($data, true); if (empty($json_data['dsDati']['TArticolo']) || empty($json_data['dsDati']['TArticoloPrezzo'])) { return; } $articoli = $json_data['dsDati']['TArticolo']; $articoli_prezzi = $json_data['dsDati']['TArticoloPrezzo']; $post_author = wp_get_current_user()->ID; // 提前构建价格索引 $price_map = []; foreach ($articoli_prezzi as $prezzo) { if ($prezzo['Nome'] === 'L1') { $price_map[$prezzo['IdArticolo']] = str_replace(' ', '', $prezzo['Valore']); } } $batch_size = 20; // 每处理20个清理一次缓存 $count = 0; foreach ($articoli as $articolo) { // 组装单个商品数据 $product_data = [ 'title' => $articolo['DescrizioneArticolo'], 'sku' => $articolo['IdArticolo'], 'aliquota' => $articolo['AliquotaIva'], 'stock' => str_replace(' ', '', $articolo['QtaDisp']), 'price' => $price_map[$articolo['IdArticolo']] ?? 0 ]; if (empty($product_data['sku']) || empty($product_data['price'])) { continue; } // 执行入库逻辑 $product_id = wc_get_product_id_by_sku($product_data['sku']); if ($product_id) { $product = wc_get_product($product_id); if ($product) { $product->set_regular_price($product_data['price']); $product->set_stock_quantity($product_data['stock']); $product->save(); } } else { $new_product = new \WC_Product(); $new_product->set_name($product_data['title']); $new_product->set_sku($product_data['sku']); $new_product->set_status('draft'); $new_product->set_regular_price($product_data['price']); $new_product->set_manage_stock('yes'); $new_product->set_stock_quantity(absint($product_data['stock'])); $new_product->save(); } // 定期清理缓存释放内存 $count++; if ($count % $batch_size === 0) { wp_cache_flush(); gc_collect_cycles(); } } }
内容的提问来源于stack exchange,提问作者Mario gasparella
相关产品推荐
相关产品推荐

