You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP遍历物流跟踪事件时如何正确设置进度条进度值

问题场景

现有一组按时间从新到旧排序的物流跟踪数组,结构如下:

Array ( 
    [0] => stdClass Object ( [message] => Out for delivery [date] => 07/06/2022 [time] => 10:30:12 AM ) 
    [1] => stdClass Object ( [message] => Consolidation arrived at gateway [date] => 07/06/2022 [time] => 8:00:07 AM ) 
    [2] => stdClass Object ( [message] => Departed sort facility [date] => 07/06/2022 [time] => 6:30:07 AM ) 
    [3] => stdClass Object ( [message] => Arrived at sort facility [date] => 07/06/2022 [time] => 12:15:05 AM ) 
    [4] => stdClass Object ( [message] => Departed sort facility [date] => 06/06/2022 [time] => 10:00:06 PM ) 
    [5] => stdClass Object ( [message] => Driver collected [date] => 06/06/2022 [time] => 4:45:07 PM ) 
    [6] => stdClass Object ( [message] => Label created [date] => 06/06/2022 [time] => 12:52:27 PM ) 
)

预先定义了进度条变量:

$progress = '0.25';

需求是根据数组中存在的物流节点,给进度条设置对应进度值。原有代码遍历数组时,多个匹配到的节点会反复覆盖$progress的值,最终结果不符合预期,原代码如下:

foreach($events as $item) {
    if ($item->message == "POD"){
        $progress = '1';
    }
    if ($item->message == "Out for delivery"){
        $progress = '0.75';
    }
    if ($item->message == "Departed sort facility"){
        $progress = '0.5';
    }
    if ($item->message == "Driver collected"){
        $progress = '0.25';
    }
}
问题原因
  • 物流数组默认按最新事件在前、最早事件在后排序,遍历过程中先匹配到高进度节点后,会继续被后面更早的低进度节点覆盖,最终拿到的是最早匹配到的低进度值
  • 所有判断条件独立执行,没有做进度值的大小比较,也没有匹配到最高优先级节点后的终止逻辑,导致无意义的重复赋值。
修复方案

方案1:映射表+取最大值(推荐,稳定性高)

提前定义节点和进度值的映射关系,遍历过程中只保留匹配到的最高进度值,不依赖数组排序规则:

// 节点-进度映射表,进度值随物流推进升高
$progressMap = [
    'Driver collected' => 0.25,
    'Departed sort facility' => 0.5,
    'Out for delivery' => 0.75,
    'POD' => 1
];
$progress = 0;

foreach($events as $item) {
    $currentMsg = $item->message;
    // 仅当当前节点在映射表中、且对应进度高于已记录值时才更新
    if (isset($progressMap[$currentMsg]) && $progressMap[$currentMsg] > $progress) {
        $progress = $progressMap[$currentMsg];
    }
}

按照给出的示例数组,最终$progress会取到最高值0.75,符合物流已经到派送环节的实际状态。

方案2:按优先级匹配+终止遍历(性能更高)

利用数组最新事件在前的排序规则,遍历判断时从最高进度节点开始匹配,匹配到即终止循环,不需要遍历全部节点:

$progress = 0;
foreach($events as $item) {
    if ($item->message == "POD"){
        $progress = 1;
        break;
    }
    if ($item->message == "Out for delivery"){
        $progress = 0.75;
        break;
    }
    if ($item->message == "Departed sort facility"){
        $progress = 0.5;
        break;
    }
    if ($item->message == "Driver collected"){
        $progress = 0.25;
        break;
    }
}

注意:该方案强依赖数组的排序规则,如果后续物流接口返回的事件顺序变为最早在前、最新在后,会直接取到最低进度值,使用前需要确认数组排序逻辑固定。

内容的提问来源于stack exchange,提问作者idwes7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 04:48:17