zoukankan      html  css  js  c++  java
  • [PHP]引用语法

    一、概述

    在php中,引用意味着用不同的symbol指向同一个变量内容。它的大致语法是:

    symbol_a =& symbol_b 

    它的正确解读方法是:把symbol_a的指向改变成指向symbol_b指向的结果上

    示例:

    $a = 1;
    $b =& $a;
    $a = 2;
    var_dump($b);//output 2

    在php结果的数据结构中,每个结果都有一个指向字段,表明这个结果被多少个symbol指向;

    示例中表达式『$a = 1』中,编译器会创建一个symbol和一个结果,这个结果只有一个symbol指向它,是刚创建的『$a』;

    接下来表达式『$b =& $a』则只创建了一个symbol『$b』,这个symbol和『$a』一样,共同指向了一个结果;

    引用的操作将symbol『$b』与symbol『$a』指向了同一个结果,当结果增加一个指向,那么它的指向字段就会加1,相反,unset()一个symbol会导致结果的指向字段减1,直到结果的指向字段为0,CG将其清除;

    这种操作有点类似于Unix的文件系统;

    二、和C语言的寻址运算符的差别

    c语言的变量可以用来保存一个地址值,『&』则作为寻址运算符,在变量前面加『&』的语义是求该变量的内存地址,然后赋值到另一个变量上,通过间接运算符『*』去读取地址指向的内容;

    在c语言中,『&』是单独的语义;

    而php则不是,根据『&』号出现的位置,有不同的解读,在下述表格先列出可以出现『&』号的位置,稍后小结会对某些结合了『&』的语句进行单独解读;

    表达式 语义
    $foo =& $bar 改变$foo的引用至$bar的引用
    function foo(&$bar){} 改变$bar的引用至外部参数的引用
    function &foo(){return $a;} 返回$a的引用
    foreach($foo AS $key => &$value) 改变$value的引用至$foo的当前遍历项(原本$value只是当前遍历项的复制值)

     

    看看这个例子:

    <?php
    function foo(&$var)
    {
        $var =& $GLOBALS["baz"];
    }
    foo($bar);
    ?>

    如果按照c语言的思维去理解,它本应该会是这样的:

    • 假设函数外部『$bar』是一个指针变量;
    • 进入foo()环境,『$var』变量被创建;
    • 『$var』被赋值为指向外部变量『$bar』的地址,函数内部把『$baz』的地址赋值给这个地址;
    • 『$bar』指向的内容被改变了,换成了指向外部『$baz』的值;

    而php是这样做的:

    • 进入foo()环境,『$var』symbol被创建;
    • 由于在函数参数声明中带有『&』运算符,所以symbol『$var』在创建后马上把指向改为跟『$bar』指向相同的一个值,『$bar』的值引用次数加1;
    • 紧接着symbol『$var』的指向再次被表达式『$var =& $GLOBALS["BAZ"]』改变为指向指向外部『$baz』的值,『$baz』的值引用次数减1,『$baz』的值引用次数加1;
    • 最后函数结束symbol『$var』被销毁,『$baz』的值引用次数减1;

    看到没,函数内部改变的,只不过是内部创建的『$var』的指向,而『$var』在函数退出后就被销毁了,跟『$bar』断绝了关系;

    三、引用返回

    『&』号除了可以用在变量赋值表达式1当中,也可以用在函数结构当中,函数名前面加『&』号表明这个函数返回一个引用:

    <?php
    class foo {
        public $value = 42;
    
        public function &getValue() {
            return $this->value;
        }
    }
    
    $obj = new foo;
    $myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
    $obj->value = 2;
    echo $myValue;                // prints the new value of $obj->value, i.e. 2.
    ?>

    如上述例子所示,为了改变一个symbol的引用,变量赋值表达式1也需要加『&』。

    注1:严格来说应该叫做改变变量引用表达式。

    四、引用传递

    当函数参数是一个引用值,那么调用这个函数的入参只能是以下3种形式:

    1. 变量,例如foo($a);
    2. new语句,例如foo(new bar());
    3. 从函数中返回引用,例如:
    <?php
    function &bar()
    {
        $a = 5;
        return $a;
    }
    foo(bar());
    ?>
  • 相关阅读:
    HNOI2017影魔
    CQOI2015任务查询系统
    ZJOI2007报表统计
    python学习之 getattr vs __get__ vs __getattr __ vs __getattribute__ vs __getitem__
    jenkins+supervisor实现django项目的自动部署(ubuntu)
    gunicorn+anaconda+nginx部署django项目(ubuntu)
    uwsgi+anaconda+nginx部署django项目(ubuntu下)
    es过滤集提升权重
    一道Python面试题:给出d = [True, False, True, False, True],请利用列表d,只用一句话返回列表[0,2,4]
    从一道Python面试题说起(大神勿入)
  • 原文地址:https://www.cnblogs.com/yiyide266/p/12957675.html
Copyright © 2011-2022 走看看