手机版

对PHP引用的深入分析()

时间:2021-09-10 来源:互联网 编辑:宝哥软件园 浏览:

什么是参考?在PHP中引用意味着用不同的名称访问相同的变量内容。这不像指向C的指针,相反,引用是符号表别名。请注意,在PHP中,变量名和变量内容是不同的,所以相同的内容可以有不同的名称。最接近的类比是Unix文件名和文件本身。——变量名是一个目录条目,而变量内容是文件本身。在Unix文件系统中,引用可以被视为硬链接。

引用做什么PHP的引用允许两个变量指向相同的内容。意思是,这样做的时候:

?PHP $ a=$ b;这意味着$a和$b指向同一个变量。

注释:

这里的$a和$b完全相同,这并不是说$a指向$b,反之亦然,而是说$a和$b指向同一个地方。

注释:

如果复制了带有引用的数组,其值将不会被取消引用。对于将值传递给函数的数组也是如此。

注释:

如果未定义的变量通过引用赋值,通过引用参数传递或通过引用返回,将自动创建该变量。

示例#1使用了对未定义变量的引用

?phpffunction foo($ var){ } foo($ a);//$a被“创建”并赋给null $ b=array();foo($ b[' b ']);var_dump(array_key_exists('b ',$ b));//bool(true)$ c=new StdClass;foo(c-d美元);var_dump(property_exists($c,' d ');//bool(真)?相同的语法可以用在返回引用的函数中,也可以用在新的运算符(PHP 4.0.4和更高版本)中:

?PHP $ bar=new foo class();$ foo=find _ var($ bar);由于PHP 5,new会自动返回一个引用,所以在这里使用=已经过时了,会生成E_STRICT级别的消息。

注释:

不使用运算符就可以复制对象。如果在类中使用$this,它将作用于类的当前实例。未使用的赋值将复制此实例(如对象),而$this将作用于此副本,这并不总是期望的结果。由于性能和内存消耗问题,您通常只想处理一个实例。

虽然您可以使用@运算符来抑制构造函数中的任何错误消息,例如@new,但在使用new语句时,它没有任何作用。这是Zend引擎的一个限制,会导致解析错误。

警告

如果给定了对函数内部声明为全局变量的引用,则该引用仅在函数内部可见。您可以通过使用$GLOBALS数组来避免这种情况。

示例2引用了函数中的一个全局变量

?php$var1='示例变量';$ var2=函数global _ references($ use _ globals){ global $ var1,$ var2if(!$ use _ globals){ $ var2=$ var1;//仅在函数内部可见} else { $ GLOBALS[' var2 ']=$ var1;//在全局上下文中也可见} } global _ references(false);echo“var2”设置为“$ var2”\ n;//var2设置为“”global _ references(true);echo“var2”设置为“$ var2”\ n;//var2设置为“示例变量”?将全球$var。as $ var=$ GLOBALS[' var '];简称。因此,将其他引用分配给$var只会改变局部变量的引用。注释:

如果在foreach语句中使用引用为变量赋值,被引用的对象也将被更改。

示例#3引用和foreach语句

?PHP $ ref=0;$ row=$ refforeach (array(1,2,3) as $row) { //do某物} echo $ ref//3 -迭代数组的最后一个元素?引用做的第二件事是通过引用传递变量。这是通过在函数中创建一个局部变量来实现的,该变量引用调用范围内的相同内容。例如:

?phpffunction foo($ var){ $ var;} $ a=5;foo(一美元);会赚到6美元。这是因为变量$var指向与foo函数中$a相同的内容。更详细的解释见参考变速器。

引用做的第三件事是引用返回。

引用什么都不是如前所述,引用不是指针。这意味着以下结构不会产生预期效果:

?phpffunction foo($ var){ $ var=$ GLOBALS[' baz '];} foo($ bar);这将使foo函数中的$var变量在调用该函数时绑定到$bar,但随后会重新绑定到$GLOBALS['baz']。通过引用机制将$bar绑定到函数调用范围内的其他变量是不可能的,因为函数foo中没有变量$bar(表示为$var,但$var在调用符号表中只有变量内容,没有名称到值的绑定)。您可以使用reference return来引用函数选择的变量。

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

?phpffunction foo($ var){ $ var;} $ a=5;foo(一美元);//$a是6吗?注意,在函数调用中没有引用符号——,只有在函数定义中。仅函数定义就足以使参数通过引用正确传递。如果在最新版本的PHP中用于foo($ a);您将收到一条警告,“调用时间传递引用”已过期。

以下内容可以通过引用传递:

变量,例如foo($a)New语句,例如foo(new foobar())从函数返回一个引用,例如:

?phpffunction bar(){ $ a=5;返回$ a;} foo(bar());有关详细说明,请参考参考报告。没有其他表达式可以通过引用传递,结果是未定义的。例如,以下传递的示例无效:

?phpffunction bar()//注意缺少的{ $ a=5;返回$ a;} foo(bar());//致命错误foo ($ a=5)既然PHP 5 . 0 . 5//表达式,不是变量foo(5) //致命错误?PHP 4.0.4及更高版本中提供了这些条件。

引用返回引用返回在您想要使用函数来查找引用应该绑定到哪个变量时使用。不要通过返回引用来提高性能,引擎足够聪明,可以自我优化。有合理的技术原因才退参考!要返回引用,请使用以下语法:

?phpclass foo { public $ value=42公共函数GetVaLue(){ return $ this-value;} } $ obj=new foo$ MyVaLue=$ obj-GetVaLue();//$myValue是对$obj-value的引用,值为42。$ obj-value=2;echo $ myValue//打印$obj-value的新值,即2。在这个例子中,getValue函数返回的对象的属性将被赋值,而不是复制,就像没有引用语法一样。

Note:不同于参数传递。这里,必须在两个地方使用符号——,以指示返回引用而不是普通副本。它还表明$myValue是作为引用的绑定,而不是普通的赋值。

注:如果您试图从这样的函数返回一个引用:return($ this-value);这将不起作用,因为您试图返回表达式的结果,而不是引用的变量。只能从函数中返回引用变量——。没有别的办法。如果代码试图返回动态表达式或新运算符的结果,将会发出一个E_NOTICE错误,因为PHP 4.4.0和PHP 5.1.0。

?phpffunction test(){ static $ b=0;//声明静态变量$ b=$ b 1;echo $ b;返回$ b;} $ a=test();//这个语句将输出$b的值为1 $ a=5;$ a=test();//这个语句将输出$b的值为2 $ a=test();//这个语句将输出$b的值为3 $ a=5;$ a=test();//这个语句将输出$b的值是6?以$a=test()的方式调用函数只会将函数的值赋给$a,但是$a的任何更改都不会影响函数中的$b。但是以$a=test()的方式调用函数,将$b变量的内存地址指向与$a变量相同的地方返回$b,相当于这个)所以改变$a的值同时改变$b的值,所以执行$ a=test();$ a=5;后来,b美元的价值变成了5。

unset reference当unset是一个引用时,它只会中断变量名和变量内容之间的绑定。这并不意味着可变内容已经被破坏。例如:

?PHP $ a=1;$ b=$ a;联合国索赔集(美元);不是未设置的$b,只是$ a。

将其与Unix的unlink call进行比较可能会有所帮助。

引用位置很多PHP语法结构都是通过引用机制实现的,所以上面提到的所有引用绑定也适用于这些结构。上面已经提到了一些结构,例如引用传递和返回。使用引用的其他结构有:

全局引用当变量用global $var声明时,它实际上建立了对全局变量的引用。也就是说,这样做是一样的:

?PHP $ var=$ GLOBALS[' var '];这意味着,例如,取消设置$var不会取消设置全局变量。

unset($a)的结果不同于$a=null的结果。如果这个内存块只有一个$a的映射,unset($a)就相当于$a=null,这个内存的引用计数变成0,自动回收;如果这个块中有两个$a和$b的映射,unset($a)将导致$a=null,而$b将保持不变,而$a=null将导致$a=$b=null。

原因:如果一个变量赋值为null,则该变量对应的内存块的引用计数会直接设置为0,并自动回收。

$this在对象的方法中,$this总是对调用它的对象的引用。

引用的作用如果程序比较大,引用同一个对象的变量比较多,而你又想在使用完之后手动清除对象,我个人建议用''然后用$var=null清除。在其他时候,您应该使用php5的默认方法。另外,对于php5中大型数组的传输,建议使用“”来节省内存空间。

这是另一集。php中指向地址(像指针一样)的功能不是用户自己实现的,而是Zend core实现的。php采用“写时复制”的原则,即指向同一地址的变量或对象除非发生写操作,否则不会被复制。

通俗的谈话

1:如果有以下代码,

?ph $ a=' ABC$ b=$ a;实际上,此时$a和$b都指向同一个内存地址,但是$a和$b并不占用不同的内存。

2:如果在上面的代码中添加以下代码,

$ a=' EFG ';由于$a和$b指向的内存的数据需要重写一次,Zend core会自动判断为$b自动生成$a的数据副本,重新申请一个内存进行存储。

版权声明:对PHP引用的深入分析()是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。