PHP foreach遍历数组追加键值后原数组无新增字段问题排查
问题复现
现有代码如下:
$campaignUserModel = new CampaignUserModel(); $subcontractors = $campaignUserModel ->select('campaigns_users.*, users.fullname user_fullname') ->join('users', 'users.id = campaigns_users.user_id') ->where('campaign_id', $id) ->findAll(); $postModel = new PostModel(); foreach ($subcontractors as $subcontractor) { $subcontractor_posts = $postModel ->where('user_id', $subcontractor['id']) ->where('campaign_id', $id) ->countAllResults(); $subcontractor['posts_count'] = $subcontractor_posts; echo "<pre>"; var_dump($subcontractor); echo "</pre>"; } echo "<pre>"; var_dump($subcontractors); echo "</pre>";
现象:循环内打印单个$subcontractor时能看到新增的posts_count字段,循环结束后打印整个$subcontractors数组,所有元素都没有该字段。
错误原因
PHP的foreach默认按值传递遍历,循环中使用的$subcontractor是原数组对应元素的拷贝副本,不是原元素本身。你在循环内对副本的所有修改,都不会同步到原数组上,所以循环结束后原数组自然不会保留新增的字段。
修复方案
有两种常用修复方式,按需选择即可:
- 方案1:遍历使用引用传递,直接操作原数组元素
注意遍历结束后必须unset掉引用变量,避免后续逻辑误修改数组最后一个元素。foreach ($subcontractors as &$subcontractor) { $subcontractor_posts = $postModel ->where('user_id', $subcontractor['id']) ->where('campaign_id', $id) ->countAllResults(); $subcontractor['posts_count'] = $subcontractor_posts; } unset($subcontractor); // 释放引用 - 方案2:通过键名直接修改原数组,不需要用引用,更不容易出隐性bug
foreach ($subcontractors as $key => $subcontractor) { $subcontractor_posts = $postModel ->where('user_id', $subcontractor['id']) ->where('campaign_id', $id) ->countAllResults(); // 直接定位原数组对应键的元素修改 $subcontractors[$key]['posts_count'] = $subcontractor_posts; }
内容的提问来源于stack exchange,提问作者Lidia K.
相关产品推荐
相关产品推荐

