您的位置 首页 php

每天一个PHP语法四引用使用及实现

说明

这里基于php7.2.5进行测试,php7之后内部结构变化应该不是太大,但与php5.X有差别。

什么是引用

在PHP中引用是一种数据类型(结构),是指 指向同一个类型的数据结构,来看具体存储结构

 struct _zend_reference {
  // 引用计数用于垃圾回收  先忽略
zend_refcounted_h gc; 
  // zval是另一个变量  zval还记得吗 存储变量的结构
  // 这里val指向另一个zval
zval              val;
};  

如何使用

 // 定义变量
$a = "hello";
// &生成引用变量
$b = &$a;

echo $b;

echo PHP_EOL;  
 php hello.php

hello  

结果大家都知道,$b与$a的值是相同的,而且你还知道,修改$b同时也会作用与$a.

 $a = "hello";
$b = &$a;

echo "b:".$b;

echo PHP_EOL;

$b = "world";

echo "a:".$a;

echo PHP_EOL;  
 php hello.php

b:hello
a:world  

如何实现

回忆zval的格式执行第一句时,生成的数据结构是这样的(简版示意图,真实结构复杂)

当执行$b = &$a时,&$a会先生成引用类型的数据结构,然后 引用的zval指向之前的hello的结构, $a,$b则共同指向引用结构。

那么在修改$b时,实际是修改了引用类型指向的zend_value,所以导致$a的值也发生了变化。

小结

php中使用&生成一个引用类型的数据,这个引用的zval指向原变量所指向的zval, 变量则会指向这个应用结构,当发生引用赋值之后,被赋值的变量也会指向这个引用,更改其中任何一个变量,所有的变量都会发生变化。类似于你大名叫大壮, 小名叫小壮, 但是身份证都是xxoo100, 无论修改大壮还是小壮的身份证,他始终只有一个身份证。

扩展

我们可能听过取地址符这么一种说法,那么在C语言或者GO中,通过使用&可以获取到变量的内存地址。

 #include <stdio.h>
#include<string.h>

int main()
{
char str[] = "hello";
  // &获取变量的内存地址
printf("%p\n", &str);
}
  
 gcc pointer.c -o pointer
./pointer

0x7ffee6d3292a  

但是PHP的&并不是获取变量的地址,这是需要注意的。

unset引用变量

 unset($b);
echo "a:".$a;

echo PHP_EOL;
echo "b:".$b;

echo PHP_EOL;  
 php hello.php

a:world
PHP Notice:  Undefined variable: b  

unset($b)之后,只是销毁了变量b及b对引用的指向,没有影响$a。

foreach中的引用

 
$list = [
    ['id' => 3, 'total' => 3],
    ['id' => 4, 'total' => 4],
    ['id' => 5, 'total' => 5],
];

foreach ($list as $key => &$info) {
    $info['total'] = $info['total'] + 3;
}

print_r($list);

// 一顿操作
$info['name'] = "hello";
print_r($info);
  
 php hello.php

Array
(
    [0] => Array
        (
            [id] => 3
            [total] => 6
        )

    [1] => Array
        (
            [id] => 4
            [total] => 7
        )

    [2] => Array
        (
            [id] => 5
            [total] => 8
        )

)


Array
(
    [id] => 5
    [total] => 8
    [name] => hello
)  

这里在foreach之后需要把info unset掉防止发生数据问题。

总结

PHP中通过&获取对变量的引用,实质是多个变量通过中间引用类型(不是指向内存地址),指向同一个值。

文章来源:智云一二三科技

文章标题:每天一个PHP语法四引用使用及实现

文章地址:https://www.zhihuclub.com/150859.shtml

关于作者: 智云科技

热门文章

网站地图