最新公告
  • 欢迎您光临波比源码,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • PHP引用传递与引用&一些用法介绍

    引用是什么

    在 PHP 中引用意味着用不同的名字访问同一个变量内容,这并不像 C 的指针,替代的是,引用是符号表别名,注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字,最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身,引用可以被看作是 Unix 文件系统中的 hardlink。

    引用做什么

    PHP 的引用允许用两个变量来指向同一个内容。

    当 $a =& $b; 时 $a 和 $b 指向了同一个变量。

    提示:$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方。

    可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值,语法如下:

    1. <?php  
    2. function foo(&$var)  
    3. {  
    4.     $var++;  
    5. }  
    6.    
    7. $a=5;  
    8. foo($a);  
    9. echo $a
    10. // 输出的是:6 

    PHP引用符&

    关于php的引用(就是在变量或者函数、对象等前面加上&符号)的作用,我们先看下面这个程序。代码如下:

    1. <?php 
    2. $a = 100; //声明变量a 
    3. $b = &$a//声明变量b,引用自变量a 
    4. echo "$a <br />";   
    5. echo "$b <br />"
    6. $a++; //变量a自增1 
    7. echo "$a <br />"
    8. echo "$b <br />";//查看变量b,也增加了1,说明使用的是同一存储单元 
    9. ?> 
    10. //程序运行结果: 
    11. //100  
    12. //100  
    13. //101  
    14. //101 

    很多人误解php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。

    php默认为传值传递,代码如下:

    1. <?php     
    2. $a = 20; 
    3. $b = $a
    4. $a = $a + 10;  
    5. echo $a.' and '.$b;  
    6. ?> 
    7. //程序运行结果: 
    8. //30 and 20 

    要是想变为地址传递需要加&,既代码如下:

    1. <?php 
    2. $a = 20; 
    3. $b = &$a;  
    4. $a = $a + 10;  
    5. echo $a.' and '.$b;  
    6. ?> 

    就是说,&把$a的地址传给了$b,这样的话这两个变量现在共享一个内存的存储区域,就是说它们的值是一样的。

    同样的语法可以用在函数中,它返回引用,以及用在 new 运算符中,代码如下:

    1. <?php  
    2. $bar =& new fooclass();  
    3. $foo =& find_var($bar);  
    4. ?> 

    引用做的第二件事是用引用传递变量,这是通过在函数内建立一个本地变量,并且该变量在呼叫范围内引用了同一个内容来实现的,说的通俗点就是一个函数的参数是一个本地变量的引用,下面再举例说明一下:

    1. <?php 
    2. function foo(&$val1$val2) { 
    3.  $val1 += 1; 
    4.  $val2 += 1; 
    5. $a=5; 
    6. $b=10; 
    7. foo($a,$b); 
    8. echo $a
    9. echo $b
    10. ?> 

    运行这段代码是给函数传递两个参数,一个是引用$a的内容,一个是$b的值,在执行此函数后,发现$a的内容改变了,而$b的内容则没有变化。

    PHP引用以及误区

    PHP中的引用可以理解成变量的别名,由于PHP的变量名是存储在符号表(symbol table)中的,变量内容是存储在堆中,引用就是用符号表中的不同符号(symbol)名称来访问同一存储内容,和Unix文件系统中的hardlink是同一个概念,比如实例代码如下:

    1. <?php 
    2. $a = 1; 
    3. $b = &$a//$a与$b指向同一内容 
    4. $b = 2; 
    5. echo $b//2 
    6. echo $a//2 
    7. ?> 

    传递引用

    引用传递很简单,就是一个「&」符号,比如如下代码:

    1. <?php 
    2. function foo(&$a) { 
    3.   $a = 2; 
    4. $b = 1; 
    5. foo($b); 
    6. echo $b//2 
    7. ?> 

    返回引用

    大多数情况下并不需要返回引用来提高性能,zend引擎会自己进行优化,但是如果你非得返回引用得话,可以按照以下方式来返回引用,代码如下:

    1. <?php 
    2. class foo { 
    3.     public $value = 42; 
    4.     public function &getValue() { // 需要一个"&" 
    5.         return $this->value; 
    6.     } 
    7. $obj = new foo; 
    8. $myValue = &$obj->getValue(); // 还需要一个"&",$myValue是对class foo中的$value的引用 
    9. $obj->value = 2;              // 修改对象的$value属性 
    10. echo $myValue;                // 输出2,$myValue与class foo中的$value值相同 
    11. ?> 

    与指针的区别

    引用与指针很像,但是其并不是指针,看如下的代码:

    1. <?php 
    2.     $a = 0; 
    3.     $b = &a; 
    4.     echo $a//0 
    5.     unset($b); 
    6.     echo $a//0 
    7. ?> 

    由于$b只是$a的别名,所以即使$b被释放了,$a没有任何影响,但是指针可不是这样的,看如下代码:

    1. #include <stdio.h> 
    2. int main(int argc, char const *argv[]) { 
    3.     int a = 0; 
    4.     int* b = &a; 
    5.     printf("%in", a); //0 
    6.     free(b); 
    7.     printf("%in", a); //*** error for object 0x7fff6350da08: pointer being freed was not allocated 

    由于b是指向a的指针,所以释放了b的内存之后,再访问a就会出现错误,比较明显的说明了PHP引用与C指针的区别。

    对象与引用

    在PHP中使用对象的时候,大家总是被告知“对象是按照引用传递的”,其实这是个误区,PHP的对象变量存储的是此对象的一个标示符,在传递对象的时候,其实传递的就是这个标示符,而并不是引用,看如下代码:

    1. <?php 
    2. $a = new A; 
    3. $b = $a;     
    4. $b->testA = 2; 
    5. /* 
    6.  * 此时$a,$b的关系: 
    7.  *        +———–+      +—————–+ 
    8.  * $a –> | object id | —> | object(Class A) | 
    9.  *        +———–+      +—————–+ 
    10.  *                               ^ 
    11.  *        +———–+          | 
    12.  * $b –> | object id | ———+ 
    13.  *        +———–+     
    14.  * 
    15.  * 
    16.  */ 
    17. $c = new B; 
    18. $a = $c
    19. $a->testB = "Changed Class B"
    20. /* 
    21.  * 此时$a,$b,$c的关系: 
    22.  *        +———–+      +—————–+ 
    23.  * $b –> | object id | —> | object(Class A) | 
    24.  *        +———–+      +—————–+ 
    25.  *                                
    26.  *        +————+           
    27.  * $a –> | object id2 | ————-+ 
    28.  *        +————+              | 
    29.  *                                    v 
    30.  *        +————+      +—————–+ 
    31.  * $c –> | object id2 | —> | object(Class B) | 
    32.  *        +————+      +—————–+ 
    33.  */ 
    34. echo "object a: "; var_dump($a); //["testB"]=> string(15) "Changed Class B" 
    35. echo "object b: "; var_dump($b); //["testA"] => int(2) 
    36. echo "object c: "; var_dump($c); //["testB"]=> string(15) "Changed Class B" 
    37. ?> 

    如果对象是按照引用传递的,那么$a, $b, $c输出的内容应该一样,事实上结果并非如此,看下面通过引用传递对象的列子:

    1. <?php 
    2. $aa = new A; 
    3. $bb = &$aa;  // 引用  
    4. $bb->testA = 2; 
    5. /* 
    6.  * 此时$aa, $bb的关系: 
    7.  * 
    8.  *         +———–+      +—————–+ 
    9.  * $bb –> | object id | —> | object(Class A) | 
    10.  *         +———–+      +—————–+ 
    11.  *              ^                   
    12.  *              | 
    13.  * $aa ———+  
    14.  * 
    15.  * 
    16.  */ 
    17. $cc = new B; 
    18. $aa = $cc
    19. $aa->testB = "Changed Class B"
    20. /* 
    21.  * 此时$aa, $bb, $cc的关系: 
    22.  * 
    23.  *         +———–+      +—————–+ 
    24.  *         | object id | —> | object(Class A) | 
    25.  *         +———–+      +—————–+ 
    26.  *               
    27.  * $bb —->—–+       
    28.  *               | 
    29.  * $aa —->—–+ 
    30.  *               |   
    31.  *               v    
    32.  *         +————+       
    33.  *         | object id2 | ————–+  
    34.  *         +————+               | 
    35.  *                                      v 
    36.  *         +————+      +—————–+ 
    37.  * $cc –> | object id2 | —> | object(Class B) | 
    38.  *         +————+      +—————–+ 
    39.  */ 
    40. echo "object aa: "; var_dump($aa); //["testB"]=>string(15) "Changed Class B" 
    41. echo "object bb: "; var_dump($bb); //["testB"]=>string(15) "Changed Class B" 
    42. echo "object cc: "; var_dump($cc); //["testB"]=>string(15) "Changed Class B" 
    43. ?> 

    此时$aa,$bb,$cc三者内容完全一样,所以可以看出对象并不是按照引用传递,要尽快走出这个误区.

    波比源码 – 精品源码模版分享 | www.bobi11.com
    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

    波比源码 » PHP引用传递与引用&一些用法介绍

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    波比源码
    一个高级程序员模板开发平台
    升级波友尊享更多特权立即升级