• PHP引用与global操作符


    普通类型变量的赋值与引用

    • 实例 1
         $a = "ABC" ;  
         $b   =& $a ;
         //此时$b$a就是同一内存的两个不同名字(表示同一个人),
         //若使用unset($b)则只是将$b这个变量指示符(身份证)去掉了,
         //$b所指向的内存还可以访问,因为有$a指向它;
         //简而言之,$a,$b就是一个人身份的证明
         //而“ABC”(value值)就是实际的人
         //unset$a)或unset($b)就是注销身份证明,
         //当一个人所有的身份证明都被注销以后,这个人就不能被访问了。
         //因此引用操作实际就是将身份证明复制一份而已,应该很好理解吧*/
         echo   $a ; // 这里输出: ABC  
         echo   $b ; // 这里输出: ABC  
         $b = "EFG" ;  
         echo   $a ; // 因为$a$b指的是同一个人,所以$a的值也变为EFG  
         echo   $b ; // 这里输出 EFG    
    • 实例 2
         $a   =   1 ;  
         $b   =&   $a ;  
         unset  ( $a );  
         echo $b; // 输出:1:  

    对象的引用(类类型的赋值就是引用)

      class fooclass{  
        public $att ;   
    }  
    $a = new fooclass();  
    $b = $a;   
    $a->att = 1;  
    $b->att = 2;  
    echo 'a obj:',($a->att),'<br>';  //2
    echo 'b obj:',($b->att);  //2

    函数传参时使用引用

        $ b = 2
        funtion change(&$a)//定义方法与c/c++中使用引用的方式类似
        {
            $a = 4;
        }
        change($b);
        echo $b;//ouput4

    函数返回引用

    function   & test()  
    {  
         static   $b = 0 ; // 申明一个静态变量  
         $b = $b + 1 ;  
         echo   $b ;  
         return   $b ;  
    }  
    $a = test(); // 这条语句会输出 $b 的值 为1  
    $a = 5 ;  
    $a = test(); // 这条语句会输出 $b 的值 为 2  
    $a =& test(); // 这条语句会输出 $b 的值 为 3  (注意函数的定义以及调用时都要使用&操作符)
    $a = 5 ;  
    $a = test(); // 这条语句会输出 $b 的值 为 6

    数组类型变量的赋值不是引用

    $arr_1 = [1,2,3];
    $arr_2 = $arr_1;//在php中array与object是不同的类型,虽然对象的赋值就是引用赋值(在php5.0以后),数组这里可以简单地认为就是新开辟了一块内存(深入来讲,其实存在“引用计数、写时拷贝”的机制)
    $arr_2[0] = 2;
    foreach ($arr_1 as $value)
    {
        echo "value_of_arr1=".$value."<br>";
    }
    
    foreach ($arr_2 as $value)
    {
        echo "value_of_arr2=".$value."<br>";
    }
    /*
    结果如下:
    value_of_arr1=1
    value_of_arr1=2
    value_of_arr1=3
    value_of_arr2=2
    value_of_arr2=2
    value_of_arr2=3
    */

    结论: PHP 的数组赋值是 copy 而非引用,赋值过程会创建新的数组赋予被赋值的变量。在新变量上的数组操作并不会影响到原数组变量中的内容


    引用数组中的元素,引发的” 魔法 “

    • 实例 1
    $a = array(21, 7);
    $c = & $a[0];
    $b = $a;
    $b[0]= 1;
    $b[1]=2;
    
    var_dump($a);
    echo '<br/>';
    var_dump($b);
    echo '<br/>';
    var_dump($c);
    echo '<br/>';
    
    // Output:
    /*  array(2) { [0]=> &int(1) [1]=> int(7) } 
        array(2) { [0]=> &int(1) [1]=> int(2) } 
        string(2) "21"
    */
    // 可以看到$a[0]与$b[0]均变为类引用类型;
    • 实例 2(接实例 1)
    unset($c);
    var_dump($a);
    echo '<br/>';
    var_dump($b);
    echo '<br/>';
    /* Output:
       array(2) { [0]=> &int(1) [1]=> int(7) } 
       array(2) { [0]=> &int(1) [1]=> int(2) } 
    */
    // 此时$a[0]与$b[0]还是类引用类型;
    • 实例 3(接实例 2)
    unset($a);
    var_dump($b);
    /* output:
        array(2) { [0]=> &int(1) [1]=> int(7) }
    */
    此时$b[0]还是引用类型
    接下来就是见证奇迹的时刻啦--见证奇迹的时刻啦----见证奇迹的时刻啦---见证奇迹的时刻啦
    但是,如果本实例中不是unset($a),而是unset($b),则var_dump($a);
    可以看到结果:array(2) { [0]=> int(1) [1]=> int(7) }
    也就是说此时$a[0]又变回正常的非引用变量了

    global 操作符

    结论:
    global $a;就等价于$a = & $GLOBALS['a'];
    * 实例 1

    <?php
        $var1 = 1;
        $var2 = 2;
        function test1(){
            $GLOBALS['var2'] = &$GLOBALS['var1'];
            //$GLOBALS['var2']此时就是代表函数外$var1变量本身
        }
        test1();
        echo $var2 . "<br />";
    
        $var3 = 1;
        $var4 = 2;
        function test2(){
            global $var3;//重点:相当于$var3=& $GLOBALS['var3'];
            global $var4;
            $var4 = &$var3;
        }
        test2();
        echo $var4 . "<br />";
    ?>
    • 实例 2
    $var1 = 1;
    function test1(){
        unset($GLOBALS['var1']);
    }
    test1();
    echo $var1 . "<br />";//输出:Notice: Undefined variable: var1
    
    $var2 = 1;
    function test2(){
        global $var2;
        unset($var2);
    }
    test2();
    echo $var2;//输出1
    ?>
    /*结果:undefined variable 与1
    由此可证明global $a;就等价于$a = & $GLOBALS['a'];

    总结

    • 引用操作就是给内存取别名(或者说是给一个人多弄一个身份证明)
    • global 操作其实是偷偷使用了引用操作:
      global $a;
      等价于
      $a = & $GLOBALS['a']
    • 要想函数返回引用,需要都定义函数以及调用函数时,都使用 & 操作符;否则函数返回的不是引用

    牛刀小试

    $var1 = "Example variable";  
    $var2 = "";  
    function global_references($use_globals) {  
        global $var1, $var2;  
        if (!$use_globals) {  
            $var2 =& $var1; // $var2只在该函数内有效
        } else {  
            $GLOBALS["var2"] =& $var1; 
        }  
    }  
    global_references(false);  
    echo "var2 is set to'$var2'", '<br>'; // var2被设置为 ''  
    global_references(true);  
    echo "var2 is set to'$var2'"; // var2被设置为'Example variable'  //通过该例子可以进一步巩固我们所学的知识,聪明的你掌握了没

    参考博客:
    http://www.cnblogs.com/borage/p/3645285.html
    http://blog.csdn.net/hguisu/article/details/7454801
    http://www.cnblogs.com/ider/archive/2012/09/06/php_reference_issue.html

  • 相关阅读:
    1-1 10:超级玛丽游戏
    1-1 09:字符菱形
    【Lucene4.8教程之四】分析
    【Lucene4.8教程之六】QueryParser与Query子类:如何生成Query对象
    【Lucene4.8教程之三】搜索
    Java路径问题最终解决方案—可定位所有资源的相对路径寻址
    java.util.logging.Logger基础教程
    【Lucene4.8教程之二】索引
    【Lucene4.8教程之一】使用Lucene4.8进行索引及搜索的基本操作
    重要学习参考资料
  • 原文地址:https://www.cnblogs.com/yldf/p/11900119.html
Copyright © 2020-2023  润新知