傳值和傳引用的理解
-
請問PHP中傳值與傳引用的區別?
- 傳值: 在函數範圍內,改變變量的值不好影響到函數外邊的變量值。
- 傳引用: 在函數範圍內, 對變量值的任何改變,函數外部的變量會跟隨改變,因爲傳引用傳的是內存地址。
-
什麼時候傳值,什麼時候傳引用?
- 需要在函數內部的改變變量值的時候可以傳引用, 如
array_pop
,array_push
函數。 - 對於較大的變量傳引用較好,可以節省內存開銷,因爲傳值調用需要複製變量。
- 需要在函數內部的改變變量值的時候可以傳引用, 如
-
php7與php5引用的實現原理?
-
在php5使用的是引用計數, 使用refcount_gc來記錄次數,is_ref_gc來記錄是否爲引用類型。
-
$a = 'hello world!'
,$a
進行賦值操作,此時refcount_gc=1
。 -
$b = $a
, 此時$a
和$b
指向的是同一個結構體,並且refcount_gc=2
。 -
$c = &$b
, 此時傳址方式將$b
賦值給$c
, 此時就需要進行分離了,$a
還是指向之前的結構體,$b
和$c
指向新的結構體,$a
還是指向原來的結構體,此時$b
和$c
指向的結構體is_ref_gc=1
, 但是值和$a
中還是相等,但是需要維護兩個值爲hello wolrd!
的zval,浪費內存。
-
-
在php7中引入了_zend_reference結構體, 引用成爲一種變量類型, 其指向了一個zval結構體。
struct _zend_reference { zend_refcounted_h gc; zval val; };
當使用
&
操作變量時,會創建一個新的中間結構體_zend_reference
, 這個結構體會指向真正的zend_string
結構體,但是zend_string
結構體的引用計數並不會發生變化,同時zend_reference
結構體的引用計數爲2,$b
和$c
均變爲zend_reference
, 好處在於zend_string
始終只有一份, 節省內存開銷
-