php foreach 数组和对象并重新定义它们的值
php foreach with arrays and objects and redefining their value
我正在尝试通过数组中的对象数组进行 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;
}
为了能够在循环内直接修改数组元素,在$value之前加上&。在这种情况下,该值将通过引用分配。在您的示例代码中应如下所示:
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
$value
仅包含数组元素的副本。
您可以像这样通过 reference 传递对象:
foreach ($weights as &$value) {
$value = $value * $kg_conv;
}
注意 $value
之前的 &。
在 Whosebug 上查看 References Explained in the php documentation or 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);
再次注意 & 运算符。
但是 的解决方案可能更符合您的要求。
编辑:
在您发表评论后,我创建了以下测试用例,效果很好:
<?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)
}
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对$value
中的原始元素使用reference:
foreach ($arr as $key => &$value) {
$value = 'something'; // $value is reference, it WILL change items in $arr
}
两种方法都有效;但是,第二个内存效率更高,因为 PHP 在循环遍历数组时不必复制数组 - 它只是引用原始数组。
它不起作用,因为你不修改数据数组,你只修改从这个数组制作的副本,这是内存中的另一个数组
解决方案:(也适用于对象的字段)
$kg_conv = 2.20462262;
$weights = ['weight', 'squats','bench', 'deadlift'];
foreach ($data['progress'] as $key=>&$value) {
if ( in_array($key,$weights)
$value = $value * $kg_conv;
}
我正在尝试通过数组中的对象数组进行 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;
}
为了能够在循环内直接修改数组元素,在$value之前加上&。在这种情况下,该值将通过引用分配。在您的示例代码中应如下所示:
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
$value
仅包含数组元素的副本。
您可以像这样通过 reference 传递对象:
foreach ($weights as &$value) {
$value = $value * $kg_conv;
}
注意 $value
之前的 &。
在 Whosebug 上查看 References Explained in the php documentation or 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);
再次注意 & 运算符。
但是
编辑:
在您发表评论后,我创建了以下测试用例,效果很好:
<?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)
}
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对$value
中的原始元素使用reference:
foreach ($arr as $key => &$value) {
$value = 'something'; // $value is reference, it WILL change items in $arr
}
两种方法都有效;但是,第二个内存效率更高,因为 PHP 在循环遍历数组时不必复制数组 - 它只是引用原始数组。
它不起作用,因为你不修改数据数组,你只修改从这个数组制作的副本,这是内存中的另一个数组
解决方案:(也适用于对象的字段)
$kg_conv = 2.20462262;
$weights = ['weight', 'squats','bench', 'deadlift'];
foreach ($data['progress'] as $key=>&$value) {
if ( in_array($key,$weights)
$value = $value * $kg_conv;
}