基于MultilingualPress的20k+产品多语言关联高效实现(WordPress多站点)
20000+规模产品多语言关联批量建立优化方案
现有代码的核心问题
- 逐行单条调用API的逻辑会产生2万+次独立数据库写入请求,极易触发PHP执行超时、内存溢出导致任务中断
- 示例中的
$contentIds为重复静态结构,没有适配你已整理好的对齐列顺序CSV的读取逻辑
落地实现步骤
1. 固定映射关系前置配置
提前把3个语言对应的站点ID和CSV的列顺序做硬编码映射,避免读取过程中重复查询站点配置拖慢速度:
// 列顺序和CSV完全对齐 $csv_column_to_site = [ 0 => 1, // CSV第1列对应站点1的产品ID 1 => 2, // CSV第2列对应站点2的产品ID 2 => 3, // CSV第3列对应站点3的产品ID ];
2. 流式读取CSV降低内存占用
不要用file_get_contents把全量CSV加载进内存,逐行读取处理,就算2万行的文件也不会占满内存:
$handle = fopen(__DIR__ . '/product_language_map.csv', 'r'); // 跳过CSV表头行 fgetcsv($handle);
3. 批量攒批写入减少API调用次数
每处理500条有效关联后再统一写入,把数据库请求量从2万次压缩到40次,同时加存在性校验避免重复写入脏数据:
$batch_size = 500; $current_batch = []; $api = \Inpsyde\MultilingualPress\resolve( \Inpsyde\MultilingualPress\Framework\Api\ContentRelations::class ); while ($row = fgetcsv($handle)) { // 跳过缺ID的无效行 if (count(array_filter(array_map('trim', $row))) < 3) continue; $relation_map = []; foreach ($csv_column_to_site as $col_index => $site_id) { $post_id = (int)trim($row[$col_index]); // 校验目标站点的产品ID真实存在,避免写入无效关联 switch_to_blog($site_id); if (get_post_status($post_id) === false) { restore_current_blog(); continue 2; } restore_current_blog(); $relation_map[$site_id] = $post_id; } // 跳过已经存在的关联,避免重复写入 if (!empty($api->getRelationship($relation_map, 'post'))) continue; $current_batch[] = $relation_map; // 攒够批次量就统一执行写入 if (count($current_batch) >= $batch_size) { foreach ($current_batch as $item) { $api->createRelationship($item, 'post'); } $current_batch = []; // 每批写完清空对象缓存,释放内存 wp_cache_flush(); } } // 处理最后一批不足阈值的剩余数据 if (!empty($current_batch)) { foreach ($current_batch as $item) { $api->createRelationship($item, 'post'); } } fclose($handle);
大规模执行注意事项
- 不要在普通Web访问请求里运行该脚本,优先通过WP-CLI环境执行,无PHP最大执行时间限制,不会因超时中断
- 执行脚本前临时关闭和内容关联无关的钩子(如SEO插件元数据同步、翻译自动同步钩子),避免写入过程触发冗余逻辑拖慢速度
- 执行前提前备份MultilingualPress存储内容关联的数据库表,逻辑出错时可快速回滚
内容的提问来源于stack exchange,提问作者Kian Salout
相关产品推荐
相关产品推荐

