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


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

簡單變量和對象好理解:

<?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)

  

數組:

<?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)

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

 

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

<?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)

當數組拷貝時,數組的指針位置也隨着復制。

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

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

 

<?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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM