PHP 引用的概念
什么是引用?
在 php 中引用意味着用不同的名字访问同一个变量内容。它不是c的指针,保存的并不是内存地址,无法进行指针运算。引用只是符号表的别名。就像 unix 系统中的硬链接, windows 系统中的快捷方式。
上面是官方手册中的原文,怎么说呢,引用其实和我们印象中的c里面的指针并不是相同的概念。指针是针对真实内存的操作,引用是针对指向这个内存的符号表的操作。还是从操作系统的快捷方式来说,快捷方式是可以删的,这就是php的引用。而c不仅删了快捷方式,还把原文件也给删了,这就是c的指针操作。
上面的代码是在php中,我们把b变量指向b变量指向a,作为a的引用变量。然后删除a的引用变量。然后删除b,对$a没有任何影响。
而c中的引用指针就不行了,我们把b变量删掉后,再打印a变量就直接报错了。
虽然说php的底层也是c写得,但我们都知道c中的指针是出了名的变态,没有一定的功底非常容易出错。所以php的开发者没有暴露c的原始指针能力,而是采用了和java之类的类似的引用能力。这也是现代语言的特性,不需要我们过多的关注过于底层的能力,而将更多的时间放在业务实现上。
引用在数组和对象中的使用
如果具有引用的数组被拷贝,其值不会解除引用。对于数组传值给函数也是如此。
这个其实挺有意思的,我们对比这两个例子可以看出一个问题,t变量指向t变量指向arr[1]的引用。arr2直接=这个arr2直接=这个arr1,没有使用引用,然后arr2修改了arr2修改了arr2[1]的内容,arr1相应的内容也发生了改变,如果unset掉arr1相应的内容也发生了改变,如果unset掉t变量,则$arr1相应的内容就不会发生改变。对此,我在文档中找到了下面的解释:
由于php内部工作的特殊性,如果对数组的单个元素进行引用,然后复制数组,无论是通过赋值还是通过函数调用中的值传递,都会将引用复制为数组的一部分。这意味着对任一数组中任何此类元素的更改都将在另一个数组(和其他引用中)中重复,即使数组具有不同的作用域(例如,一个是函数内部的参数,另一个是全局的)!在复制时没有引用的元素,以及在复制数组后分配给其他元素的引用,将正常工作(即独立于其他数组)。
不仅仅是数组,对象的引用也会有一些好玩的问题。
上面例子中有三个对象,o1、o1、o2、o3,其中,o3,其中,o2是对o1的引用,o1的引用,o3是直接赋值为o1。对o1。对o2属性的操作不仅会反映在o1中,也会反映到o1中,也会反映到o3中。其实我们之前专门有一篇文章就讲的这个问题,首先对象默认赋值就是引用,其次这个例子很好地证明了引用就是一个符号表的绑定。删除了快捷方式对原始对象和其他快捷方式没有任何影响。
引用的传递
关于引用在方法参数上的传递,最重要的是记住两点:一是方法内部修改了变量外部也会变,这是引用的特性嘛;二是只能传递变量、new 语句、从函数中返回的引用三种类型。
引用的返回
引用的返回并不是经常使用的一个能力。文档中的原文是:不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!
当你想要返回一个引用变量的时候,一定要给方法定义和方法调用的时候都使用&符号。这个是需要注意的点。当其他地方修改原本的变量值或者返回的变量值经过修改后,都会影响到所有调用这个值的地方。所以说,引用的返回是比较危险的,因为你不清楚什么时候在什么地方这个值可能发生了修改,对于bug的排查会非常困难。
引用的取消
取消引用其实就是直接unset掉变量就可以了。但是一定要记住,php中的引用是指向的符号表,对原始真实的值是不起作用的,所以即使unset掉了最原始的那个变量,对其它引用赋值的变量也不会有影响!!
总结
这一次算是比较彻底的把引用说了个透。关于php的引用只要记住了它的定义就非常好理解了,最直观的就是当成是操作系统的快捷方式就好了,并没有我们想象中的那么难,和c的指针相比真的只是娃娃级别,多多练习多多复习自然就能很好地掌握使用啦!
测试代码:
以上就是php的中引用的概念的详细内容,更多关于php 引用的资料请关注其它相关文章!
上一篇: PHP垃圾回收机制的一些理解