PHP数组参数按值,在通过引用循环数组项时被修改

Posted

技术标签:

【中文标题】PHP数组参数按值,在通过引用循环数组项时被修改【英文标题】:PHP array argument by value, gets modified when looping the array items by reference 【发布时间】:2012-06-15 19:49:00 【问题描述】:

我在将数组按值传递给函数时遇到了问题。

我检查了代码,在函数内部,数组通过引用循环获取元素。

我惊讶地发现,在循环之后,数组项被标记为已引用。我不知道这是什么意思,但一定是我的问题的根源。

让我举个例子来说明这一点。

<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);

$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);

function dummy($arg) 
    foreach($arg as &$item) 
        $item[0] = 3;
        
    dummy2($arg);
echo '--3--';var_dump($arg);


function dummy2($arg) 
    foreach($arg as &$item) 
        $item[1]=9;
    
echo '--2--';var_dump($arg);

?>

在这段代码之后,我希望在第 3 点中,$arg 将只有一个元素,但它有两个,因此它已被 dummy2 函数修改。

输出如下:

--1--array(1)  [0]=> array(1)  [0]=> int(0)   
--2--array(1)  [0]=> &array(2)  [0]=> int(3) [1]=> int(9)   
--3--array(1)  [0]=> &array(2)  [0]=> int(3) [1]=> int(9)   
--4--array(1)  [0]=> array(1)  [0]=> int(0)  

为什么数组被引用循环后标记为&array? 如何避免?

【问题讨论】:

【参考方案1】:

您需要取消设置通过引用捕获的循环变量:

<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);

$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);

function dummy($arg) 
    foreach($arg as &$item) 
        $item[0] = 3;
    
    unset($item);
    dummy2($arg);
echo '--3--';var_dump($arg);


function dummy2($arg) 
    foreach($arg as &$item) 
        $item[1]=9;
    
    unset($item);
echo '--2--';var_dump($arg);

?>

见documentation for foreach,有一个大大的红色警告说:

$value 的引用和最后一个数组元素即使在 foreach 循环。建议通过 unset() 销毁。

【讨论】:

【参考方案2】:

使用 key =&gt; value 对并在函数中返回数组

<?php

    error_reporting(E_ALL);
    ini_set('display_errors' , 1);

    $a = array( array(0) );

    echo '--1--';var_dump($a);

    $a = dummy($a);

    echo '--4--';var_dump($a);

    function dummy($arg) 

        foreach($arg as $key => $value) 

            $arg[$key][0] = 3;
        

        return dummy2($arg);
    

    function dummy2($arg) 

        foreach($arg as $key => $value) 

           $arg[$key][1]=9;
        

        return $arg;
    
?>

http://codepad.org/f30c6FUj

【讨论】:

以上是关于PHP数组参数按值,在通过引用循环数组项时被修改的主要内容,如果未能解决你的问题,请参考以下文章

PHP 数组的拷贝是按值传递 or 按引用传递

PHP是不是优化数组类型的函数参数,而不是通过引用显式传递,当它们没有被修改时?

php按值复制数组元素,而不是按引用

java数组

java 值传递 数组传递

Java方法中传递数组与改变数组值的问题