3

I'm trying to understand something about arrays in for each loops that might be obvious to many.

When i loop through my multi-dimensional array, i attempt to find sub arrays with no third element. If they have no third element, i want to add a third element to that sub array with a specific value.

$testArray = array (
    array("Green", "Yellow", "Blue"),
    array("Brown", "Silver"),
    array("Orange", "Pink", "Black"),
);

When i use the foreach loop:

foreach ( $testArray as $key => $array ) {
    if (count($array) == '2') {
        $array[] = "None";
    };
}

No errors are thrown but nothing happens. When i use the for each loop:

foreach ( $testArray as $key => $array ) {
    if (count($array) == '2') {
        $testArray[$key][] = "None";
    };
}

It works as expected.

Sorry for the long preamble, my questions is:

Why aren't these two foreach loops doing the same thing? Thanks!

4

3 回答 3

4

因为您需要“通过引用”访问 $testArray 条目

foreach ( $testArray as &$array ) {
    if (count($array) == 2) {
        $array[] = "None";
    };
}
unset($array);
于 2013-06-27T14:23:53.237 回答
2

这里的问题在于 foreach 迭代可迭代对象并按值设置迭代变量。这意味着$array您在 中处理的 与 的foreach值不同$testArray

为了解决这个问题(并避免引入$index变量来改变数组中的项目),您需要告诉 foreach通过引用传递值。引用是 PHP 对 C 风格指针的回答。如果一个变量引用另一个变量,则两个变量都指向同一个值,因此对一个变量的内容的修改实际上是对另一个变量的修改。在您的foreach中,您可以使用&$array让循环通过$testArray引用而不是通过值向您传递项目:

foreach ( $testArray as $key => &$array ) {
    if (count($array) == '2') {
        $array[] = "None";
    }
}

键盘演示

这与 PHP 的引用一致,其中一个变量可以引用另一个变量,如下所示:

$a = array(1, 2, 3);
$b = &$a;
$b[] = 4;

print_r($a); // 1, 2, 3, 4

键盘演示

您会在函数中遇到类似的现象:

function byValue($a) {
    $a[] = 4;
}

function byRef(&$a) {
    $a[] = 5;
}

$a = array(1, 2, 3);

byValue($a);
print_r($a); // 1, 2, 3

byRef($a);
print_r($a); // 1, 2, 3, 5

键盘演示

PHP 文档的参考部分有一些关于foreach. 还要注意这个(有点)相关但有趣的阅读foreach和参考资料


此外,如果您不知道,请注意:}在 PHP 中关闭块后不需要分号,除非您正在执行诸如为变量分配闭包之类的操作:

$someFunc = function($a) { return $a; }; //need one here

if(1 + 2 == 4) {
   echo "I just broke math";
} // but you don't need one here
于 2013-06-27T14:31:03.237 回答
0

foreach循环不通过引用传递元素。要让第一个数组做你想做的事,它必须是:

foreach ( $testArray as $key => &$array ) {
    if (count($array) == '2') {
        $array[] = "None";
    };
}
于 2013-06-27T14:24:08.740 回答