php引用使用不恰當而產生問題的地方

2022-03-10 22:13:44 字數 2616 閱讀 2302

php變數的引用,如果使用的恰當,會帶來效率的提公升,相反,效率下降

$array = range(0, 1000000);$

ref =&$array;

var_dump(count($array));

//

count是個內建函式,引數只接收傳值,但現在傳入的引數$array是個引用,由於在php5中,某個值是不能引用變數和非引用變數之間使用

針對這個例子來說,即在count內部,php引擎會copy乙個$arrray指向的zval,所以效率就降下來了

如果傳的count的引數不是引用,那麼count內部不會做copy動作, 在copy內部,接收的引數其實也會指向 $array指向的zval,因為php陣列的名稱就代表了在記憶體的位址

$a="123";

$b=$a; // $a,$b 指向同乙個zval_1, type=is_string, refcount_gc=2, is_ref_gc=0

$c=&$b; //由於同一值(zval)不能被引用變數和非引用變數之間使用,要分離  , $c, $d指向zval_2 type=is_string, refcount_gc=2, is_ref_gc=1

$d=$c //如上也要分離,儘管$d的值沒有重新賦值 $d 指向zval_3,type=is_string, ref_count_gc=1,is_ref_gc=0

在php7中,某個值是可能在引用變數和非引用變數之間使用的,只有當發生變化時,才會copy乙份zval

$c=&$b; 因為有$c,$d兩個變數 zval.value.ref->gc.refcount=2  zval.value.ref->val.value.str.gc.refcount=2 ($a,$b)

$d=$c   zval.value.ref->val.value.str.gc.refcount=3 ($a,$b ,$d) 

struct

_zval_struct v;

uint32_t type_info;

} u1;

union u2;

};typedef union _zend_value ww;

} zend_value;

struct

_zend_refcounted ;

typedef

struct

_zend_refcounted_h v;

uint32_t type_info;

} u;

} zend_refcounted_h;

所以說php當初被發明出來,是為了更方便使用者, 這樣的結果就是使用方可以隨意寫**,但php引擎就要做大量的維護工作

那麼php的引數是如何執行的?

function test(&$b)

$a=1

;test($a);

$a的值為2

如果說

function test($b)

$a=1

;test($a);

$a的結果是1

因為我們形參是實參的乙個拷貝,對拷貝的操作不會影響到實參

$a=1;

首先分配乙個zval*的記憶體,填充zval中的value(zva.value.lval=1)以及type(zva.type=is_long)

然後放到active_symbol_table這個hashtable中, key為'a' value為乙個zval指標,該指標指向上面的zval

$a="abc"

通過zend_hash_quick_get(eg(active_symbol_table),'a', ptr) 得到key為'a' 的對應的value的記憶體位址,即上面zval的位址,再設定其zval.value.str.val="abc";

$a=2;

通過zend_hash_quick_get(eg(active_symbol_table),'a', ptr) 得到key為'a' 的對應的value的記憶體位址,即上面zval的位址,

因為此時zval的型別為is_string,故要釋放到zva.value.str這段記憶體

再設定其zval.value.lval=2;

$b=$a;

首先zend_hash_quick_get(eg(active_symbol_table),'a')得到變數a 對應的zval的位址

然後zend_hash_quick_set(eg(active_symbol_table),'b', 上面zval對應的位址);

$c=&$b

分離zval, 再次分配乙個zval型別的記憶體,copy value和type,初始為refcount_gc以及is_ref_gc

zend_hash_quick_set(eg(active_symbol_table),'b', 新的zval對應的位址);

zend_hash_quick_set(eg(active_symbol_table),'c', 新的zval對應的位址);

$c=5;

zend_hash_quick_get(eg(active_symbol_table),'c')得到變數c 對應的zval的位址

zval.value.lval=5

php 引用不是指標

指標會存放位址值 引用僅僅是乙個標識 b 3 b 就是 globals b 的引用,相當於是 b globals b class foo obj new foo myvalue obj getvalue myvalue is a reference to obj value,which is 42....

如何正確使用PHP 引用

角色 姓名 王笨笨 愛稱 狗蛋兒 生澀的概念 引用就是別名,多個名字指向同乙個變數內容,沒有重複冗餘的記憶體開銷。a runbaby b a var dump a,b string 7 runbaby string 7 runbaby bug 因為我們錯誤使用,導致錯誤。我們的工作是什麼 寫bug,...

php 引用 mysql PHP使用MySQL

準備工作 php 5 及以上版本建議使用以下方式連線 mysql mysqli extension i 意為 improved pdo php data objects pdo 應用在 12 種不同資料庫中,mysqli 只針對 mysql 資料庫。所以,如果你的專案需要在多種資料庫中切換,建議使用...