
本文介绍如何将 woocommerce 订单中多个商品的交付日期进行归并,将具有相同日期的商品 id 合并为数组,并重构原始数据结构,实现按日期维度聚合展示。
本文介绍如何将 woocommerce 订单中多个商品的交付日期进行归并,将具有相同日期的商品 id 合并为数组,并重构原始数据结构,实现按日期维度聚合展示。
在处理 WooCommerce 订单商品的自定义元字段(如 'Daty dostaw')时,常需对分散在不同商品中的重复日期进行逻辑聚合。例如:商品 A 有日期 ['13-08-2022', '25-08-2022'],商品 B 有 ['25-08-2022', '31-08-2022'],目标是将共享的 '25-08-2022' 提取为独立条目,其 product_id 为 [988012, 988087],其余唯一日期则保留原商品 ID。
以下是一个健壮、可读性强的实现方案,采用「两阶段处理」:先建立日期索引映射,再重构结果数组。
✅ 推荐实现(已测试 & 优化)
$order = wc_get_order(988613);
$original_data = [];
// 第一阶段:构建原始扁平化数据(与原逻辑一致)
$counter = 1;
foreach ($order->get_items() as $item) {
$daty_dostaw = $item->get_meta('Daty dostaw');
$product_id = $item->get_product_id();
if (empty($daty_dostaw)) continue;
$dates = array_map('trim', explode(',', $daty_dostaw));
$original_data[$counter] = [
'product_id' => $product_id,
'data' => $dates
];
$counter++;
}
// 第二阶段:按日期归并 — 核心逻辑
$merged = [];
$date_to_products = []; // key: '25-08-2022' → value: [988012, 988087]
// 1. 扫描所有商品,收集每个日期对应的所有 product_id
foreach ($original_data as $item) {
foreach ($item['data'] as $date) {
if (!isset($date_to_products[$date])) {
$date_to_products[$date] = [];
}
$date_to_products[$date][] = $item['product_id'];
}
}
// 2. 构建最终合并数组:每个日期生成一个条目
$index = 1;
foreach ($date_to_products as $date => $product_ids) {
// 若该日期仅属于一个商品,则 product_id 保持标量(非数组),提升兼容性
$pid_value = count($product_ids) === 1 ? $product_ids[0] : $product_ids;
$merged[$index] = [
'product_id' => $pid_value,
'data' => [$date] // 注意:每个条目 data 是单元素数组,保持结构统一
];
$index++;
}
// 可选:按日期升序排序(假设格式为 DD-MM-YYYY,需转换为 YMD 比较)
uksort($merged, function($a, $b) use ($merged) {
$dateA = DateTime::createFromFormat('d-m-Y', $merged[$a]['data'][0]) ?: new DateTime();
$dateB = DateTime::createFromFormat('d-m-Y', $merged[$b]['data'][0]) ?: new DateTime();
return $dateA $dateB;
});
// 输出结果
print_r($merged);
? 关键说明与注意事项
-
结构一致性:每个结果项的
'data'均为单元素数组(如['25-08-2022']),便于后续foreach遍历,避免类型判断。 -
单/多商品自动适配:当某日期只被一个商品使用时,
product_id为整数;多个商品时自动转为数组——无需额外is_array()判断即可安全渲染。 -
空值防护:跳过空
'Daty dostaw'元字段,防止explode()报错或产生无效日期。 -
日期排序建议:示例中提供了基于
DateTime的自然排序逻辑,确保输出按时间先后排列(适用于DD-MM-YYYY格式)。 -
性能提示:该算法时间复杂度为 O(n×m)(n=商品数,m=平均日期数),对普通订单(≤100 商品)完全高效;如需处理超大规模数据,可改用
array_reduce+array_flip进一步优化。
✅ 最终输出效果(符合需求)
Array
(
[1] => Array
(
[product_id] => Array
(
[0] => 988012
[1] => 988087
)
[data] => Array
(
[0] => 25-08-2022
)
)
[2] => Array
(
[product_id] => 988012
[data] => Array
(
[0] => 13-08-2022
)
)
[3] => Array
(
[product_id] => 988012
[data] => Array
(
[0] => 30-08-2022
)
)
[4] => Array
(
[product_id] => 988087
[data] => Array
(
[0] => 31-08-2022
)
)
[5] => Array
(
[product_id] => 988087
[data] => Array
(
[0] => 30-09-2022
)
)
)
此方案简洁、可靠、易于维护,可直接集成至 WooCommerce 钩子或自定义报表逻辑中。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











