PHP引用

【引用是什麼】php

  PHP中的引用是用不一樣的名字訪問同一個變量內容。不一樣與C的指針,PHP中的引用是zval標識符的別名。ide

 1 //對未定義的變量進行引用賦值、引用參數傳遞或引用返回時,將自動建立該變量
 2 function refTst(&$var){
 3     var_dump($var);
 4 }
 5 
 6 refTst($a);    //$a自動被建立並賦值爲NULL
 7 
 8 refTst($ary['k']);
 9 var_dump(array_key_exists('k',$ary));    //bool(true)
10 
11 $obj=new StdClass();
12 refTst($obj->p);
13 var_dump(property_exists($obj,'p'));    //bool(true)
對未定義的變量進行引用賦值、引用參數傳遞或引用返回時,將自動建立該變量
 1 //函數內引用全局變量
 2 function globalRef(){
 3     global $var1,$var2;    //global $var是$var=&$GLOBALS['var']的簡寫
 4 
 5     $var2=$var1;
 6     echo $var2,$GLOBALS['var2'],PHP_EOL;    //11
 7     
 8     $var2=2;
 9     echo $var2,$GLOBALS['var2'],PHP_EOL;    //22
10 
11     $var2=&$var1;
12     echo $var2,$GLOBALS['var2'],PHP_EOL;    //12
13 
14     $var2=3;
15     echo $var2,$GLOBALS['var2'],PHP_EOL;    //32
16     echo $var1,$GLOBALS['var1'],PHP_EOL;    //33
17 }
18 
19 $var1=1;
20 $var2=0;
21 globalRef();
函數聲明爲global的變量則是對全局變量的引用

【引用傳參】函數

 1 //引用傳參
 2 function refTst(&$var){
 3     ++$var;
 4 }
 5 
 6 $var=1;
 7 refTst($var);    //若是寫成refTst(&$var)將出現FATAL_ERROR。解決方法是設置php.ini中allow_call_time_pass_reference=true
 8 echo $var;    //2
 9   
10 call_user_func_array('refTst',array(&$var));    //第二個參數中必須加&,不然出現E_WARNING。call_user_func()中的參數不能是引用。
11 echo $var;    //3

【引用返回】this

 1 //引用返回
 2 function &refReturn{
 3     static $var=0;
 4     ++$var;
 5     return $var;
 6 }
 7 
 8 $v=refReturn()    //$v不是函數的引用返回,跟普通函數調用同樣。$v和$val的值都是1
 9 $v=5;    //$var任然是1
10 $v=refRetrun()    //$v和$val的值都是2
11 
12 $v=&refReturn()    //引用返回的正確調用格式,$v是$var的引用。$v和$var都是3
13 $v=5;    //$v和$var都是5
14 $v=refReturn();    //$v和$var都是6
 1 class Talker{
 2     private $data='Hi';
 3     
 4     public function & get(){
 5         return $this->data;//不是return($this->data);
 6     }
 7 
 8     public function out(){
 9         echo $this->data;
10     }
11 }
12 
13 $obj=new Talker();
14 $dt=&$obj->get();
15 
16 $obj->out();
17 
18 $dt=' ,How';
19 $obj->out();
20 
21 $dt=' Are';
22 $obj->out;
23 
24 $dt=' You!';
25 $obj->out;
26 
27 //運行結果
28 Hi,How Are You!
引用返回的對象操做

 【對象的引用】spa

1 class Cls{
2     public $data='Obj Data';
3 }
4 
5 $obj=new Cls();
6 echo obj->data;    //Obj Data
7 $obj1=$obj;    //PHP5中對象賦值是個引用過程(PHP4中是個拷貝過程),PHP5默認以引用方式調用對象。若要創建對象副本,能夠重寫其__clone()方法;
8 $obj1->data='Obj1 Data';
9 echo $obj->data;    //Obj1 Data

【寫時拷貝】指針

PHP中對地址的指向功能是由Zend核心實現的,PHP採用的是寫時拷貝的原理,即:除非發生寫操做,不然指向同一個地址的變量或對象是不會被拷貝的。code

 1 //寫時拷貝
 2 $ary=array('a','b','c');
 3 $ary1=$ary;    //程序運行到這裏,$ary和$ary1都指向同一塊內存。
 4 
 5 function getAryCnt(&$ary){
 6     echo count($ary);
 7 }
 8 getAryCnt($ary);    //經過引用將$ary傳遞給getAryCnt()函數。此時,Zend引擎會認爲getAryCnt()可能會改變$ary,因此此時將爲$ary1從新申請一塊內存單元並保存$ary的數據拷貝。這個過程就是「寫時拷貝」。
 9 
10 //修改getAryCnt()
11 function getAryCnt($ary){
12     echo count($ary);
13 }
14 getAryCnt($ary);    //將getAryCnt()改成非引用傳參時,不會改變$ary的值,因此沒有出現寫時拷貝。

【取消引用】對象

 1 //取消引用用unset()實現
 2 error_reptting(0);
 3 function refTst(){
 4     $var=&$GLOBALS['var'];    //等同於global $var;
 5     $var=5;
 6     unset($var);    //只是消除$var的引用,而對全局變量$GLOBALS['var']沒影響
 7     var_dump($var);    //NULL
 8     echo $GLOBALS['var'];    //5
 9 }
10 
11 $var=1;
12 refTst();
13 echo $var;    //5
相關文章
相關標籤/搜索