
array_merge() 会重置数字索引,导致无法保留你指定的日期作为键;正确做法是直接赋值(如 $arr[$key] = $value)或使用 + 数组合并运算符。
php 中使用 array_merge 合并带自定义键的数组时的键重置问题详解:`array_merge()` 会重置数字索引,导致无法保留你指定的日期作为键;正确做法是直接赋值(如 `$arr[$key] = $value`)或使用 `+` 数组合并运算符。
在 PHP 中,array_merge() 的行为常被误解——它并非简单“追加”键值对,而是按类型分别处理:对于字符串键,它会保留原键名;但对于数字键(整型索引),它会自动重新编号,从 0 开始连续递增。这正是你遇到问题的根本原因:
$dailyArray = []; $dailyArray = array_merge($dailyArray, [1 => 'mon']); // ✅ 保留键 1 $dailyArray = array_merge($dailyArray, [2 => 'tue']); // ✅ 保留键 2 // → 结果:[1 => 'mon', 2 => 'tue'] $dailyArray = []; $dailyArray = array_merge($dailyArray, [1 => 'mon']); $dailyArray = array_merge($dailyArray, [3 => 'wed']); // ❌ 键 3 会被重置为 0! // → 实际结果:[0 => 'mon', 1 => 'wed'] ← 键丢失!
这是因为 array_merge() 将所有纯数字键视为“索引数组”,强制重组为连续整数索引。你代码中 $day 是整型(如 4, 5),但 array_merge() 不识别其语义,仅当作普通数字键处理,最终触发重索引。
✅ 推荐解决方案:避免 array_merge,直接赋值
$dailyArray = []; // 初始化空数组
// 示例:生成 2022-11 月前 6 天(周一至周六)的 weekday 映射
$year = 2022;
$month = 11;
for ($d = 1; $d format('j'); // 如 '1', '2'...
$weekday = strtolower((new DateTime($dateStr))->format('D')); // 'mon', 'tue'...
$dailyArray[$dayNum] = $weekday; // ? 直接赋值,完美保留数字键
}
print_r($dailyArray);
// 输出:
// Array (
// [1] => mon
// [2] => tue
// [3] => wed
// [4] => thu
// [5] => fri
// [6] => sat
// )
✅ 替代方案:使用 + 运算符合并(仅适用于键不冲突)
$dailyArray = []; $dailyArray += [1 => 'mon']; $dailyArray += [2 => 'tue']; $dailyArray += [3 => 'wed']; // ✅ 保留所有数字键,不重置
⚠️ 注意:+ 是左优先合并,若键重复,左边值保留;而 array_merge() 是右覆盖。
? 关于循环截止条件的修正
你提到 (int)date_create($j)->format('w') 0(周日)~ 6(周六),所以
// 循环直到周六('w' == 6)
while ((int)(new DateTime($j))->format('w') <p>? <strong>最佳实践总结</strong> </p>
- ✅ 为保持自定义数字键(如日期 1, 15, 31),永远避免对数字键数组使用 array_merge();
- ✅ 优先使用 $array[$key] = $value 直接赋值;
- ✅ 若需合并多个预定义键值对,用 + 运算符更安全;
- ✅ 使用 DateTime 对象替代 date_create()(更现代、可读性更强);
- ✅ 验证 format('w') 范围:0=Sun, 1=Mon, ..., 6=Sat —— 判断周六请用 == 6 或
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











