PHP 數組的拷貝是按值傳遞 or 按引用傳遞

在記憶中 PHP 簡單變量的拷貝是按值傳遞,數組和對象的拷貝是按引用傳遞,即經過引用來實現。php

簡單變量和對象好理解:html

<?php

// 簡單變量的拷貝
$a = 'human';
$b = $a;
$b = 'cat';
var_dump($a); // string 'human' (length=5)

// 對象的拷貝
class A{}
$a = new A();
$b = $a;
$b->name = 'jack';
var_dump($a); // object(A)[1] public 'name' => string 'jack' (length=4)

對象 $a 和 對象 $b 的內存地址指向了同一個地方,即針對 $a 和 $b 所作的操做都針對同一個實例。數組

PHP 中能夠經過 clone 關鍵字按值拷貝對象:函數

<?php

class A{
	public $name = 'Vardy';
}
$a = new A(); $b = clone $a; $b->name = 'dee'; var_dump($a); // object(A)[1] public 'name' => string 'Vardy' (length=5) var_dump($b); // object(A)[2] public 'name' => string 'dee' (length=3)

  

數組:post

<?php

// 數組的拷貝
$a = ['human', 'orc'];
$b = $a;
$b[0] = 'elve';
var_dump($a);
// array (size=2)
//   0 => string 'human' (length=5)
//   1 => string 'orc' (length=3)

這樣看,數組的拷貝是按值傳遞的.url

 

另外一個例子 數組的迭代器:spa

<?php

$a = ['human', 'orc', 'elven', 'undead'];
next($a);

$b = $a; // 此時指針位置也隨着數組的複製而複製

var_dump(current($a)); // string 'orc' (length=3)
var_dump(current($b)); // string 'orc' (length=3)

當數組拷貝時,數組的指針位置也隨着複製。.net

(next:http://php.net/manual/zh/function.next.php指針

current:http://php.net/manual/zh/function.current.phpcode

 

<?php

$a = ['human', 'orc', 'elven', 'undead'];
end($a);
next($a); // 數組指針非法,返回 FALSE

$b = $a;

var_dump(current($a)); // string 'human' (length=5)
var_dump(current($b)); // boolean false

當數組在拷貝前,指針的位置是非法時,拷貝後分別打印兩個數組指針所指向的當前單元時,出現了不同的狀況。

緣由是數組變量發生拷貝後,兩個變量中先發生寫操做的,其指針被初始化,即指向第一個元素,而 current 方法也會產生寫操做,所以 $a 的數組指針當前指向的是 'human',而 $b  current 方法則返回 FALSE。

 

如下代碼同理, $b 首先發生了寫操做:

<?php

$a = ['human', 'orc', 'elven', 'undead'];
end($a);
next($a);

$b = $a;

$b[] = 'dwarf';

var_dump(current($a)); // boolean false
var_dump(current($b)); // string 'human' (length=5)

  

解析:數組的拷貝是值傳遞。PHP 在管理內存方面有一個機制叫寫時複製(COW,Copy On Write),保證了變量間複製值不浪費內存:當一個變量的值複製到另外一個變量時,PHP 沒有爲複製值使用更多的內存,相反,它會更新符號表來講明兩個變量擁有相同的內存塊,因此當執行下面的代碼時並無建立一個新的數組:

<?php

$a = ['human', 'orc', 'elven', 'undead'];
$b = $a;

當修改了 $a 或 $b 任意一個副本時,PHP 將分配所需的內存來進行復制:

$b[] = 'dwarf';

  

 

 

參考:

php基礎語法之數組和數組指針

php中引用&的真正理解-變量引用、函數引用、對象引用

Programming PHP 3rd Edition

相關文章
相關標籤/搜索