贝利信息

如何在 Laravel 中安全地遍历对象数组并根据 CNPJ 拆分数据

日期:2026-01-17 00:00 / 作者:心靈之曲

本文介绍在 laravel 中遍历对象数组时,如何避免因使用 `next()` 导致的“trying to get property of non-object”错误,并提供更健壮、可读性更强的拆分逻辑(如按唯一 cnpj 分组为两个数组)。

在 Laravel(或纯 PHP)中处理对象数组时,若需基于当前项与下一项的比较进行逻辑分支(例如按 cnpj 是否变化来拆分数组),直接使用 next() 是危险且不可靠的——因为当循环到达末尾时,next

() 返回 false 或 null,而代码仍尝试访问 $next->cnpj,从而触发 “Trying to get property 'cnpj' of non-object” 错误。该问题在数组长度为 2 时尤为明显:第一次迭代后 next() 指向第二项,第二次迭代后 next() 已越界,返回非对象值。

更合理、更符合 Laravel 风格的解决方案是分离「识别分组依据」与「分配数据」两个阶段,避免在遍历中依赖不稳定的内部指针。以下是推荐实现:

✅ 推荐方案:两阶段分组(清晰、安全、可扩展)

// 第一阶段:提取所有唯一 CNPJ 并排序(确保顺序确定)
$cnpjs = array_unique(array_column($finances, 'cnpj'));
sort($cnpjs);

// 初始化结果数组
$aiuaEd = []; // 默认组(匹配第一个 CNPJ)
$aiua   = []; // 可选组(匹配第二个 CNPJ,仅当存在多个时)

// 第二阶段:按 CNPJ 归类(安全、无边界风险)
foreach ($finances as $finance) {
    if (count($cnpjs) > 1 && $finance->cnpj === $cnpjs[1]) {
        $aiua[] = $finance;
    } else {
        $aiuaEd[] = $finance; // 包含所有首个 CNPJ 及唯一 CNPJ 的情况
    }
}
? 关键改进说明:使用 array_column($finances, 'cnpj') 替代手动 foreach 提取,更简洁高效;array_unique() + sort() 确保 $cnpjs 是有序的数值索引数组(如 [0 => '111', 1 => '222']),避免键名混乱;完全规避 next(),杜绝空对象访问风险;逻辑明确:仅当存在至少两个不同 CNPJ 时才启用双数组逻辑,否则全部归入 $aiuaEd。

⚠️ 注意事项与进阶建议

综上,放弃对内部数组指针(next()/prev())的依赖,转而采用声明式分组策略,不仅彻底解决空对象错误,还提升了代码可读性、可维护性与 Laravel 生态兼容性。