PHP引用传递与引用&一些用法介绍
发布:smiling 来源: PHP粉丝网 添加日期:2014-02-22 11:59:35 浏览: 评论:0
引用是什么
在 PHP 中引用意味着用不同的名字访问同一个变量内容,这并不像 C 的指针,替代的是,引用是符号表别名,注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字,最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身,引用可以被看作是 Unix 文件系统中的 hardlink。
引用做什么
PHP 的引用允许用两个变量来指向同一个内容。
当 $a =& $b; 时 $a 和 $b 指向了同一个变量。
提示:$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方。
可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值,语法如下:
- <?php
- function foo(&$var)
- {
- $var++;
- }
- $a=5;
- foo($a);
- echo $a;
- // 输出的是:6
PHP引用符&
关于php的引用(就是在变量或者函数、对象等前面加上&符号)的作用,我们先看下面这个程序。代码如下:
- <?php
- $a = 100; //声明变量a
- $b = &$a; //声明变量b,引用自变量a
- echo "$a <br />";
- echo "$b <br />";
- $a++; //变量a自增1
- echo "$a <br />";
- echo "$b <br />";//查看变量b,也增加了1,说明使用的是同一存储单元
- ?>
- //程序运行结果:
- //100
- //100
- //101
- //101
很多人误解php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。
php默认为传值传递,代码如下:
- <?php
- $a = 20;
- $b = $a;
- $a = $a + 10;
- echo $a.' and '.$b;
- ?>
- //程序运行结果:
- //30 and 20
要是想变为地址传递需要加&,既代码如下:
- <?php
- $a = 20;
- $b = &$a;
- $a = $a + 10;
- echo $a.' and '.$b;
- ?>
就是说,&把$a的地址传给了$b,这样的话这两个变量现在共享一个内存的存储区域,就是说它们的值是一样的。
同样的语法可以用在函数中,它返回引用,以及用在 new 运算符中,代码如下:
- <?php
- $bar =& new fooclass();
- $foo =& find_var($bar);
- ?>
引用做的第二件事是用引用传递变量,这是通过在函数内建立一个本地变量,并且该变量在呼叫范围内引用了同一个内容来实现的,说的通俗点就是一个函数的参数是一个本地变量的引用,下面再举例说明一下:
- <?php
- function foo(&$val1, $val2) {
- $val1 += 1;
- $val2 += 1;
- }
- $a=5;
- $b=10;
- foo($a,$b);
- echo $a;
- echo $b;
- ?>
运行这段代码是给函数传递两个参数,一个是引用$a的内容,一个是$b的值,在执行此函数后,发现$a的内容改变了,而$b的内容则没有变化。
PHP引用以及误区
PHP中的引用可以理解成变量的别名,由于PHP的变量名是存储在符号表(symbol table)中的,变量内容是存储在堆中,引用就是用符号表中的不同符号(symbol)名称来访问同一存储内容,和Unix文件系统中的hardlink是同一个概念,比如实例代码如下:
- <?php
- $a = 1;
- $b = &$a; //$a与$b指向同一内容
- $b = 2;
- echo $b; //2
- echo $a; //2
- ?>
传递引用
引用传递很简单,就是一个「&」符号,比如如下代码:
- <?php
- function foo(&$a) {
- $a = 2;
- }
- $b = 1;
- foo($b);
- echo $b; //2
- ?>
返回引用
大多数情况下并不需要返回引用来提高性能,zend引擎会自己进行优化,但是如果你非得返回引用得话,可以按照以下方式来返回引用,代码如下:
- <?php
- class foo {
- public $value = 42;
- public function &getValue() { // 需要一个"&"
- return $this->value;
- }
- }
- $obj = new foo;
- $myValue = &$obj->getValue(); // 还需要一个"&",$myValue是对class foo中的$value的引用
- $obj->value = 2; // 修改对象的$value属性
- echo $myValue; // 输出2,$myValue与class foo中的$value值相同
- ?>
与指针的区别
引用与指针很像,但是其并不是指针,看如下的代码:
- <?php
- $a = 0;
- $b = &a;
- echo $a; //0
- unset($b);
- echo $a; //0
- ?>
由于$b只是$a的别名,所以即使$b被释放了,$a没有任何影响,但是指针可不是这样的,看如下代码:
- #include <stdio.h>
- int main(int argc, char const *argv[]) {
- int a = 0;
- int* b = &a;
- printf("%in", a); //0
- free(b);
- printf("%in", a); //*** error for object 0x7fff6350da08: pointer being freed was not allocated
- }
由于b是指向a的指针,所以释放了b的内存之后,再访问a就会出现错误,比较明显的说明了PHP引用与C指针的区别。
对象与引用
在PHP中使用对象的时候,大家总是被告知“对象是按照引用传递的”,其实这是个误区,PHP的对象变量存储的是此对象的一个标示符,在传递对象的时候,其实传递的就是这个标示符,而并不是引用,看如下代码:
- <?php
- $a = new A;
- $b = $a;
- $b->testA = 2;
- /*
- * 此时$a,$b的关系:
- * +-----------+ +-----------------+
- * $a --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- * ^
- * +-----------+ |
- * $b --> | object id | ---------+
- * +-----------+
- *
- *
- */
- $c = new B;
- $a = $c;
- $a->testB = "Changed Class B";
- /*
- * 此时$a,$b,$c的关系:
- * +-----------+ +-----------------+
- * $b --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- *
- * +------------+
- * $a --> | object id2 | -------------+
- * +------------+ |
- * v
- * +------------+ +-----------------+
- * $c --> | object id2 | ---> | object(Class B) |
- * +------------+ +-----------------+
- */
- echo "object a: "; var_dump($a); //["testB"]=> string(15) "Changed Class B"
- echo "object b: "; var_dump($b); //["testA"] => int(2)
- echo "object c: "; var_dump($c); //["testB"]=> string(15) "Changed Class B"
- ?>
如果对象是按照引用传递的,那么$a, $b, $c输出的内容应该一样,事实上结果并非如此,看下面通过引用传递对象的列子:
- <?php
- $aa = new A;
- $bb = &$aa; // 引用
- $bb->testA = 2;
- /*
- * 此时$aa, $bb的关系:
- *
- * +-----------+ +-----------------+
- * $bb --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- * ^
- * |
- * $aa ---------+
- *
- *
- */
- $cc = new B;
- $aa = $cc;
- $aa->testB = "Changed Class B";
- /*
- * 此时$aa, $bb, $cc的关系:
- *
- * +-----------+ +-----------------+
- * | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- *
- * $bb ---->-----+
- * |
- * $aa ---->-----+
- * |
- * v
- * +------------+
- * | object id2 | --------------+
- * +------------+ |
- * v
- * +------------+ +-----------------+
- * $cc --> | object id2 | ---> | object(Class B) |
- * +------------+ +-----------------+
- */
- echo "object aa: "; var_dump($aa); //["testB"]=>string(15) "Changed Class B"
- echo "object bb: "; var_dump($bb); //["testB"]=>string(15) "Changed Class B"
- echo "object cc: "; var_dump($cc); //["testB"]=>string(15) "Changed Class B"
- ?>
此时$aa,$bb,$cc三者内容完全一样,所以可以看出对象并不是按照引用传递,要尽快走出这个误区.
Tags: PHP引用 传递 引用
- 上一篇:php字符串与字符串操作教程详解
- 下一篇:PHP入门基础之引用文件学习笔记
相关文章
- ·php引用(&)与文件引用详解(2014-08-06)
- ·php引用返回function & fun();学习笔记(2015-04-09)
- ·PHP传值与传引用的区别例子对比(2015-04-10)
- ·php 传值赋值和引用赋值笔记(2015-12-10)
- ·PHP引用符&的使用方法汇总(2015-12-12)
- ·PHP引用的调用方法分析(2019-08-18)
- ·php引用传值实例详解学习(2020-05-16)
- ·php中引用符号(&)的使用详解(2020-07-02)
- ·PHP引用(&)各种使用方法实例详解(2020-10-29)
- ·PHP基础之引用的解释3——引用的取消和定位(2021-01-02)
- ·PHP基础之引用的解释2——引用传递和返回(2021-01-02)
- ·PHP基础之引用的解释1——引用是什么、不是什么、做什么(2021-01-02)
- ·PHP的引用详解(2021-05-14)
- ·PHP如何通过传引用的思想实现无限分类(代码简单)(2021-06-20)
- ·深入理解PHP变量的值类型和引用类型(2021-06-20)
- ·PHP中引用类型和值类型功能与用法示例(2021-11-11)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)