php foreach与数组和对象,并重新定义它们的价值

时间:2015-01-03 13:28:23

标签: php arrays object foreach

我试图通过数组中的一系列对象进行操作。我没有收到错误,但似乎没有存储我试图建立的新值。我在这里找到了许多与这个问题密切相关的答案,但我不理解,我希望有人能说清楚这一点。

基本上,这会将kg转换为lbs。

    $kg_conv = 2.20462262;
    $weights = array($data['progress']->weight, $data['progress']->squats,
    $data['progress']->bench, $data['progress']->deadlift); 

    foreach ($weights as $value) {
        $value = $value * $kg_conv;
    }

数组中的值保持不变。从我读过的内容来看,我应该使用$ data [' progress']并迭代完成,但我不理解如何只引用内部的一些元素而不是他们都是。我还尝试通过将对象存储在$ progress而不是$ data [' progress']中来削减一些冗余,但仍然没有成功。

更新:以下内容无效

1

    foreach ($weights as &$value) {
        $value = $value * $kg_conv;
    }

2

    foreach ($weights as $key => &$value) {
        $value = $value * $kg_conv;
    }

3

    foreach ($weights as $key => $value) {
        $weights[$key] = $value * $kg_conv;
    }

4 个答案:

答案 0 :(得分:2)

$value仅包含数组元素的副本。

您可以通过参考传递对象,如下所示:

foreach ($weights as &$value) {
    $value = $value * $kg_conv;
}

请注意$value之前的&

请参阅php文档中的References Explained或stackoverflow上的What's the difference between passing by reference vs. passing by value?

编辑2:

但请注意,这只会更改$weights数组中的值,而不是$data['progress']中存储的对象,因为它的值已经复制$weights }。为实现此目的,您可以通过以下方式构造数据数组时引用对象属性(此步骤在我的测试用例代码中已注释掉):

$weights = array(&$data['progress']->weight, &$data['progress']->squats,
    &$data['progress']->bench, &$data['progress']->deadlift);

再次注意& 运算符。

maxpower的解决方案可能更符合您的要求。

编辑:

在您发表评论后,我创建了以下测试用例,该工作正常:

<?php
class foo {
    public $test = 5;
    public $test2 = 10;
}

$obj = new foo();
$obj2 = new foo();
$obj2->test = 3; 

$data =  array('progress' => $obj, 'p2' => $obj2);

// this copies the values into the new array
$weights = array($data['progress']->test, $data['progress']->test2);

// this makes a reference to the values, the original object will be modified
// $weights = array(&$data['progress']->test, &$data['progress']->test2);

var_dump($weights);

$kg_conv = 2.20462262;

foreach ($weights as &$value) {
    $value = $value * $kg_conv;
}
var_dump($weights);

结果是:

array(2) {
  [0]=>
  int(5)
  [1]=>
  int(10)
}
array(2) {
  [0]=>
  float(11.0231131)
  [1]=>
  &float(22.0462262)
}

答案 1 :(得分:2)

它不起作用,因为你不修改数据数组,你只修改由这个数组制作的副本,这是内存中的另一个数组

解决方案:(也适用于对象的字段)

$kg_conv = 2.20462262;
$weights = ['weight', 'squats','bench', 'deadlift']; 

foreach ($data['progress'] as $key=>&$value) {
  if ( in_array($key,$weights)
    $value = $value * $kg_conv;
}

答案 2 :(得分:0)

为了能够直接修改循环中的数组元素,在$ value之前加上&amp ;.在这种情况下,该值将通过引用分配。在您的示例中,代码应如下所示:

foreach ($weights as &$value) {
    $value = $value * $kg_conv;
}

但只有在可以引用迭代数组时(即,如果它是变量),才可以引用$ value。 您还可以使用索引直接访问数组值。这段代码也很好用:

foreach ($weights as $key => $value) {
    $weights[$key] = $value * $kg_conv;
}

更多信息:http://php.net/manual/en/control-structures.foreach.php

答案 3 :(得分:0)

PHP foreach manual详细介绍了此主题。总结一下为什么你没有看到你期望的结果,这里有一个简短的解释。

想象一下你有一个数组$arr = ['one', 'two', 'three']。当您在此阵列上执行foreach循环时,PHP将在内部创建数组的副本

foreach ($arr as $key => $value) {
    $value = 'something'; // You are modifying the copy, not the original!
}

要修改原始数组,您有两个选择。

使用$key变量访问原始数组中给定键的元素:

$arr[$key] = 'something'; // Will change the original array

告诉PHP使用reference $value中的原始元素:

foreach ($arr as $key => &$value) {
    $value = 'something'; // $value is reference, it WILL change items in $arr
}

两种方法都有效;然而,第二个是内存效率更高,因为PHP在循环时不必复制你的数组 - 它只是引用原始数据。