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

PHP中end()数组赋值未达预期,合并日期时间数组求助

咱们一个一个来解决你的问题,都是PHP里常见的小坑,别担心~

问题1:PHP中使用end()赋值不符合预期

你肯定是踩了end()函数的一个关键误区——end()返回的是数组最后一个元素的副本,不是引用,所以直接给end()的返回值赋值完全无效,根本不会修改原数组。

举个你可能写错的例子:

$arr = ['a', 'b', 'c'];
end($arr) = 'd'; // 这行代码等于白写!
print_r($arr); // 输出还是 ['a', 'b', 'c']

给你几种正确的实现方式,按需选择:

  • 如果你的PHP版本是7.3及以上,直接用array_key_last()拿到最后一个键再赋值,最简洁:
    $arr = ['a', 'b', 'c'];
    $lastKey = array_key_last($arr);
    $arr[$lastKey] = 'd';
    print_r($arr); // 输出 ['a', 'b', 'd']
    
  • 要兼容低版本PHP的话,先调用end()移动数组指针,再用key()获取最后一个元素的键:
    $arr = ['a', 'b', 'c'];
    end($arr); // 把指针移到最后一个元素
    $lastKey = key($arr); // 获取当前指针位置的键
    $arr[$lastKey] = 'd';
    print_r($arr); // 同样得到 ['a', 'b', 'd']
    
  • 如果是纯索引数组,也可以用array_pop()+array_push()组合,但这种会改变数组长度,适合只替换最后一个元素的场景:
    $arr = ['a', 'b', 'c'];
    array_pop($arr);
    array_push($arr, 'd');
    
问题2:合并同一天的时间区间,取最早start和最晚end

你的需求核心是按日期分组聚合,循环处理是可行的,但可以优化得更清晰。这里给你两种实现思路:

方式1:foreach循环(直观易懂,新手友好)

// 你的原始时间数组示例
$timeEntries = [
    ['start' => '2018-01-01 12:00', 'end' => '2018-01-01 15:00'],
    ['start' => '2018-01-01 12:00', 'end' => '2018-01-01 17:00'],
    ['start' => '2018-01-02 09:00', 'end' => '2018-01-02 11:00'],
];

$result = [];

foreach ($timeEntries as $entry) {
    // 提取日期部分作为分组键(比如'2018-01-01')
    $date = date('Y-m-d', strtotime($entry['start']));
    
    if (!isset($result[$date])) {
        // 第一次遇到这个日期,直接初始化
        $result[$date] = $entry;
    } else {
        // 对比start时间,保留更早的那个
        if (strtotime($entry['start']) < strtotime($result[$date]['start'])) {
            $result[$date]['start'] = $entry['start'];
        }
        // 对比end时间,保留更晚的那个
        if (strtotime($entry['end']) > strtotime($result[$date]['end'])) {
            $result[$date]['end'] = $entry['end'];
        }
    }
}

// 如果需要去掉日期键,转成纯索引数组,用array_values()
$result = array_values($result);
print_r($result);

方式2:array_reduce(简洁的函数式写法)

如果你喜欢函数式编程风格,用array_reduce可以一行完成分组聚合:

$timeEntries = [
    ['start' => '2018-01-01 12:00', 'end' => '2018-01-01 15:00'],
    ['start' => '2018-01-01 12:00', 'end' => '2018-01-01 17:00'],
];

$result = array_values(array_reduce($timeEntries, function($carry, $item) {
    $date = date('Y-m-d', strtotime($item['start']));
    if (!isset($carry[$date])) {
        $carry[$date] = $item;
    } else {
        // 因为你的日期格式是标准的Y-m-d H:i,直接用字符串比较min/max也有效
        $carry[$date]['start'] = min($carry[$date]['start'], $item['start']);
        $carry[$date]['end'] = max($carry[$date]['end'], $item['end']);
    }
    return $carry;
}, []));

print_r($result);

两种方式最终都会输出你想要的结果:

Array
(
    [0] => Array
        (
            [start] => 2018-01-01 12:00
            [end] => 2018-01-01 17:00
        )
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:05:05