PHP - 修改foreach循环中的当前对象

Gar*_*bit 101 php arrays foreach object

我想知道是否可以编辑foreach循环中正在处理的当前对象

我正在使用一组对象$questions,我想通过查找与我的数据库中的问题对象相关的答案.因此,对于每个问题,请获取答案对象并更新我的循环中的当前$question 内容,foreach以便我可以在其他地方输出/处理.

foreach($questions as $question){
    $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
Run Code Online (Sandbox Code Playgroud)

Ren*_*Pot 192

有两种方法可以做到这一点

foreach($questions as $key => $question){
    $questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以保存密钥,因此可以在主$questions变量中再次更新密钥

要么

foreach($questions as &$question){
Run Code Online (Sandbox Code Playgroud)

添加&将保持$questions更新.但我会说第一个被推荐,即使这个更短(见Paystey的评论)

根据PHP foreach文档:

为了能够直接修改循环中的数组元素,在$ value之前加上&.在这种情况下,该值将通过引用分配.

  • 实际上不推荐使用`foreach`中的引用,`foreach`绕过循环的值部分的方式导致不可预测的行为.它可能会更长,但你在这里使用方法1更安全. (30认同)
  • @Paystey你能引用你的消息来源或详细解释一下吗? (6认同)
  • 我刚刚花了一个困惑的时间来调试由于在 foreach 中使用引用而引起的问题。我在第二个 foreach 调用中重复使用了相同的变量名 - 因为我通过引用传递了第一个变量,所以它不断修改数组中的最后一项!使用显式索引就不会出现此问题。 (3认同)
  • 为什么操纵引用是不安全的?C/C++是否必须在不安全的地方操纵引用?这取决于你是否安全,而不是语言. (2认同)
  • @BabyAzerty:Paystey并没有说“一般”引用,而是在“ foreach”中提到了类似这样的恐怖:http://stackoverflow.com/questions/3307409/php-pass-by-reference-in-foreach(@ Nico,也仅供参考。) (2认同)

MrM*_*ees 6

当然使用array_map和使用实现ArrayAccess派生对象的容器只是一种更智能,更语义的方式来实现这个目标吗?

在我看过的大多数语言和实现中,数组映射语义都是类似的.它被设计为基于输入数组元素返回修改后的数组(高级忽略语言编译/运行时类型首选项); 循环意味着执行更多逻辑.

对于通过ID/PK检索对象,取决于你是否使用SQL(似乎建议),我会使用过滤器来确保获得有效PK的数组,然后使用逗号内爆并放入SQL IN()子句中返回结果集.它通过SQL进行一次调用而不是几次调用,优化了一些call->wait循环.最重要的是,我的代码可以很好地阅读具有一定能力的任何语言的人,我们不会遇到可变性问题.

<?php

$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);
Run Code Online (Sandbox Code Playgroud)

VS

<?php

$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
    $arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);
Run Code Online (Sandbox Code Playgroud)

如果你知道你在做什么就永远不会有可变性问题(请记住,如果你打算覆盖,$arr你可以永远$arr = array_map明确.

  • 比 foreach 更直观——这正是这个函数的设计目的。 (2认同)