各个元素的引用行为是否与数组容器的引用状态分离?

时间:2015-12-03 12:19:16

标签: php reference pass-by-reference

这是什么意思"换句话说,数组的引用行为是逐个元素定义的;单个元素的引用行为与数组容器的引用状态分离。"

如何将单个元素与数组容器的引用状态分离?我正在彻底doc,我很困惑这是什么意思?

<?php
/* Assignment of scalar variables */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c is not a reference; no change to $a or $b

/* Assignment of array variables */
$arr = array(1);
$a =& $arr[0]; //$a and $arr[0] are in the same reference set
$arr2 = $arr; //not an assignment-by-reference!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* The contents of $arr are changed even though it's not a reference! */
?>

1 个答案:

答案 0 :(得分:6)

我认为如果您使用某些ASCII艺术,您可能会更好地理解它:

第一个例子:

//Line 01
$a = 1;

----------

┌──────┐                       ┌─────┐      
│  $a  │   ─────────────────>  │  1  │
└──────┘                       └─────┘

//Line 02
$b = &$a;

----------

┌──────┐                       ┌─────┐      
│  $a  │   ─────────────────>  │  1  │
└──────┘                       └─────┘
                                  ^
┌──────┐                          │
│  $b  │   ───────────────────────┘ 
└──────┘                      

//Line 03
$c = $b;

----------

┌──────┐                       ┌─────┐      
│  $a  │   ─────────────────>  │  1  │
└──────┘                       └─────┘
                                  ^
┌──────┐                          │
│  $b  │   ───────────────────────┘ 
└──────┘                      

┌──────┐                       ┌─────┐      
│  $c  │   ─────────────────>  │  1  │
└──────┘                       └─────┘

//Line 04
$c = 7;

----------

┌──────┐                       ┌─────┐      
│  $a  │   ─────────────────>  │  1  │
└──────┘                       └─────┘
                                  ^
┌──────┐                          │
│  $b  │   ───────────────────────┘ 
└──────┘                      

┌──────┐                       ┌─────┐      
│  $c  │   ─────────────────>  │  7  │
└──────┘                       └─────┘

现在您可以看到通过引用分配变量并更改它时,它也会更改另一个变量的值。例如$a$b,如果您为$b分配5,$a也会指向5,反之亦然。

但您没有通过引用将$b分配给$c(您通过值分配进行了正常操作),因此如果您更改$c的值,则会赢得&#39 ; t更改$b(或$a)的值。

第二个例子:

//Line 01
$arr = array(1);

----------

┌───────────┐                       ┌─────┐      
│  $arr[0]  │   ─────────────────>  │  1  │
└───────────┘                       └─────┘

//Line 02
$a = &$arr[0];

----------

┌───────────┐                       ┌─────┐      
│  $arr[0]  │   ─────────────────>  │  1  │
└───────────┘                       └─────┘
                                       ^
┌──────┐                               │
│  $a  │   ────────────────────────────┘ 
└──────┘                      

//Line 03
$arr2 = $arr;

----------

┌───────────┐                       ┌─────┐      
│  $arr[0]  │   ─────────────────>  │  1  │
└───────────┘                       └─────┘
                                       ^
┌──────┐                               │
│  $a  │   ────────────────────────────┤ 
└──────┘                               │
                                       │
┌────────────┐                         │
│  $arr2[0]  │   ──────────────────────┘
└────────────┘                       

//Line 04
$arr2[0]++;

----------

┌───────────┐                       ┌─────┐      
│  $arr[0]  │   ─────────────────>  │  2  │
└───────────┘                       └─────┘
                                       ^
┌──────┐                               │
│  $a  │   ────────────────────────────┤ 
└──────┘                               │
                                       │
┌────────────┐                         │
│  $arr2[0]  │   ──────────────────────┘
└────────────┘     

现在,本手册试图解释的是:

$arr2 = $arr;

即使您没有通过引用$arr来分配数组$arr2,该数组仍然包含一个指向引用的元素!该引用仍然位于$arr2中,因此第二个数组的第一个元素也指向$arr[0]$a的引用。

也许如果您看到通过引用分配数组时的差异,并且当数组包含带引用的元素时,您可以更好地理解它:

通过引用分配的数组:

//Line 01
$arr1 = [1, 1, 1];

----------

┌─────────┐                            
│  $arr1  │         
└─────────┘                       
     │
     │
     └─────────> ┌────────────┐
                 │   Array    │          ┌─────┐  
                 │ container: │    ┌───> │  1  │
                 ├────────────┤    │     └─────┘
                 │    [0]     │ ───┘
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  1  │
                 ├────────────┤          └─────┘
                 │    [2]     │ ───┐
                 └────────────┘    │     ┌─────┐ 
                                   └───> │  1  │
                                         └─────┘

//Line 02
$arr2 = &$arr1;

----------

┌─────────┐                            
│  $arr1  │         
└─────────┘                       
     │
     │
     └─────────> ┌────────────┐
                 │   Array    │          ┌─────┐  
                 │ container: │    ┌───> │  1  │
                 ├────────────┤    │     └─────┘
                 │    [0]     │ ───┘
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  1  │
                 ├────────────┤          └─────┘
                 │    [2]     │ ───┐
     ┌─────────> └────────────┘    │     ┌─────┐ 
     │                             └───> │  1  │
     │                                   └─────┘
┌─────────┐                            
│  $arr2  │         
└─────────┘   

//Line 03 & 04
$arr2[0] = 2;
$arr2[1] = 2;

----------

┌─────────┐                            
│  $arr1  │         
└─────────┘                       
     │
     │
     └─────────> ┌────────────┐
                 │   Array    │          ┌─────┐  
                 │ container: │    ┌───> │  2  │
                 ├────────────┤    │     └─────┘
                 │    [0]     │ ───┘
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  2  │
                 ├────────────┤          └─────┘
                 │    [2]     │ ───┐
     ┌─────────> └────────────┘    │     ┌─────┐ 
     │                             └───> │  1  │
     │                                   └─────┘
┌─────────┐                            
│  $arr2  │         
└─────────┘   

正如您在此处看到的那样,由于您通过引用将$arr1分配给$arr2,因此它们都指向同一个数组。

包含引用的数组:

//Line 01
$a = 1;

----------

┌──────┐                       ┌─────┐      
│  $a  │   ─────────────────>  │  1  │
└──────┘                       └─────┘

//Line 02
$arr3 = [&$a, 1, 1];

----------

┌──────┐                        ┌─────┐      
│  $a  │   ──────────────────>  │  1  │
└──────┘                        └─────┘            
                                   ^              
┌─────────┐                        │              
│  $arr3  │                        │              
└─────────┘                        │              
     │                             │              
     │                             │              
     └─────────> ┌────────────┐    │              
                 │   Array    │    │              
                 │ container: │    │              
                 ├────────────┤    │              
                 │    [0]     │ ───┘              
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  1  │  
                 ├────────────┤          └─────┘  
                 │    [2]     │ ───┐              
                 └────────────┘    │     ┌─────┐  
                                   └───> │  1  │  
                                         └─────┘  




//Line 03
$arr4 = $arr3;

----------

┌──────┐                        ┌─────┐      
│  $a  │   ──────────────────>  │  1  │ <─────────┐
└──────┘                        └─────┘           │ 
                                   ^              │
┌─────────┐                        │              │
│  $arr3  │                        │              │
└─────────┘                        │              │
     │                             │              │
     │                             │              │
     └─────────> ┌────────────┐    │              │
                 │   Array    │    │              │
                 │ container: │    │              │
                 ├────────────┤    │              │
                 │    [0]     │ ───┘              │
                 ├────────────┤          ┌─────┐  │
                 │    [1]     │ ───────> │  1  │  │
                 ├────────────┤          └─────┘  │
                 │    [2]     │ ───┐              │
                 └────────────┘    │     ┌─────┐  │
                                   └───> │  1  │  │
                                         └─────┘  │
                                                  │
┌─────────┐                                       │
│  $arr4  │                                       │
└─────────┘                                       │
     │                                            │
     │                                            │
     └─────────> ┌────────────┐                   │
                 │   Array    │                   │
                 │ container: │                   │
                 ├────────────┤                   │
                 │    [0]     │ ──────────────────┘
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  1  │
                 ├────────────┤          └─────┘
                 │    [2]     │ ───┐
                 └────────────┘    │     ┌─────┐ 
                                   └───> │  1  │
                                         └─────┘



//Line 03 & 04
$arr4[0] = 2;
$arr4[1] = 2;

----------

┌──────┐                        ┌─────┐      
│  $a  │   ──────────────────>  │  2  │ <─────────┐
└──────┘                        └─────┘           │ 
                                   ^              │
┌─────────┐                        │              │
│  $arr3  │                        │              │
└─────────┘                        │              │
     │                             │              │
     │                             │              │
     └─────────> ┌────────────┐    │              │
                 │   Array    │    │              │
                 │ container: │    │              │
                 ├────────────┤    │              │
                 │    [0]     │ ───┘              │
                 ├────────────┤          ┌─────┐  │
                 │    [1]     │ ───────> │  1  │  │
                 ├────────────┤          └─────┘  │
                 │    [2]     │ ───┐              │
                 └────────────┘    │     ┌─────┐  │
                                   └───> │  1  │  │
                                         └─────┘  │
                                                  │
┌─────────┐                                       │
│  $arr4  │                                       │
└─────────┘                                       │
     │                                            │
     │                                            │
     └─────────> ┌────────────┐                   │
                 │   Array    │                   │
                 │ container: │                   │
                 ├────────────┤                   │
                 │    [0]     │ ──────────────────┘
                 ├────────────┤          ┌─────┐  
                 │    [1]     │ ───────> │  2  │
                 ├────────────┤          └─────┘
                 │    [2]     │ ───┐
                 └────────────┘    │     ┌─────┐ 
                                   └───> │  1  │
                                         └─────┘

即使您按价值将$arr3分配给$arr4,也可以在此处看到,而不是通过引用!该数组仍包含该引用,该引用与$a$arr3[0]共享。