zoukankan      html  css  js  c++  java
  • PHP 语法引用使用及实现

    说明

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

    什么是引用

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

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

      

    忘了的这里看 zval

    如何使用

    // 定义变量
    $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
    ", &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高级开发工程师简历打造,祝你金三银四跳槽加薪

  • 相关阅读:
    匿名对象
    封装性
    1 Django初探
    8 定制10MINs 3
    7 定制10MINs首页2
    5-1 练习css 总结
    6.定制10MINS首页1
    3-1 练习 HTML 总结
    5. css定位 居中
    4 CSS的20/80个知识点
  • 原文地址:https://www.cnblogs.com/a609251438/p/12719986.html
Copyright © 2011-2022 走看看