• PHP 引用 简单


    <?php
    //用引用解释
    
    
    ///////////////////////////////////////////////////////////////
    //1 引用是什么
    //在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名
    //php的引用并不是C的指针,只是一个指向同一地址的变量
    
    
    ///////////////////////////////////////////////////////////////
    //2 引用做什么
    //对一个未定义的变量进行引用赋值,引用参数传递或引用返回,则会自动创建该变量
    /*
    class MyStdClass{
    
    };
    
    function foo(&$val)
    { 
        //var_dump($val); 
    }
    foo($a);
    $b =array();
    foo($b['b']);
    //var_dump(array_key_exists('b',$b));
    $c = new MyStdClass;
    foo($c->b);
    //var_dump(property_exists($c,'b')); //判断对像的属性是否存在
    
    
    //如果在一个函数内部给一个声明为global的变量赋于一个引用,该引用只是在函数内部可见
    //可以用全局的$BLOBALS数组避免这一点
    
    $var1 = "Example val";
    $var2 = "";
    function global_references($use_globals)
    {
    	global $var1, $var2;
        if(!$use_globals){
        	 $var2 = & $var1; //该引用只是在函数中有用
        }else{
             $GLOBALS['var2'] = & $var1;
        }
    }
    global_references(false);
    //echo "var2 is set to".$var2."\n\t<BR>";
    global_references(true);
    //echo "var2 is set to".$var2."\n\t";
    //把global $val;当成是$var=& $GLOBALS['var']的简写,从而将其它引用赋值给$var只改变了本地变量的引用
    
    //如果在foreach语句中给一个具有引用的变量赋值,被引用的对像也被改变
    $ref = 0;
    $row = & $ref;
    foreach (array(1,2,3) as $row) {
    	# code...
    }
    //echo $ref;
    
    class reftest
    {
         public $a = 1;
         public $c = 1;
    
         public function reftest1()
         {
         	 $b = & $this->a;
         	 $b++;
         }
    
         public function reftest2()
         {
         	 $d = & $this->c;
         	 $d++;
         }
    }
    $test = new reftest();
    $test->reftest1();
    $test->reftest2();
    //echo $test->a."<BR>"; //2
    //echo $test->c;        //2
    
    
    $v1=0;
    $arrV=array(&$v1,&$v1);
    //foreach ($arrV as $v)
    //{  
      //$v1++;
      //echo $v1."\n";//现在的$v1的变量所指向的值已经是1 2了
      //echo $v."\n"; //这里的$v值是还没有添自加之前的值,
    //}
    foreach ($arrV as $key => $value) 
    {
    	# code...
    	$v1++;
    	//echo $arrV[$key]."\n";
    }
    
    // $arr1 = array(1);
    // echo "\nbefore:\n";
    // echo "\$arr1[0] == {$arr1[0]}\n"; //==1 
    // $arr2 = $arr1;
    // $arr2[0]++;
    // echo "\nafter:\n";
    // echo "\$arr1[0] == {$arr1[0]}\n"; //==1
    // echo "\$arr2[0] == {$arr2[0]}\n"; //==2
    
    
    
    // $arr3 = array(1);
    // $a =& $arr3[0];
    // echo "\nbefore:\n";
    // echo "\$a == $a\n";//==1
    // echo "\$arr3[0] == {$arr3[0]}\n";//==1
    // $arr4 = $arr3;
    // $arr4[0]++;
    // echo "\nafter:\n";
    // echo "\$a == $a\n";//==2
    // echo "\$arr3[0] == {$arr3[0]}\n"; //2
    // echo "\$arr4[0] == {$arr4[0]}\n"; //2
    //这个例子要小心哈
    */
    
    
    // function array_key_by($data, $keys, $dupl = false)
    // /* 
    //  * $data  - Multidimensional array to be keyed
    //  * $keys  - List containing the index/key(s) to use.
    //  * $dupl  - How to handle rows containing the same values.  TRUE stores it as an Array, FALSE overwrites the previous row.
    //  *          
    //  * Returns a multidimensional array indexed by $keys, or NULL if error.
    //  * The number of dimensions is equal to the number of $keys provided (+1 if $dupl=TRUE).
    //  */   
    // {
    //     // Sanity check
    //     if (!is_array($data)) return null;
        
    //     // Allow passing single key as a scalar
    //     if (is_string($keys) or is_integer($keys)) $keys = Array($keys);
    //     elseif (!is_array($keys)) return null;
    
    //     // Our output array
    //     $out = Array();
        
    //     // Loop through each row of our input $data
    //     foreach($data as $cx => $row)
    //     { 
    // 	    if (is_array($row))
    // 	    {
    // 	      //$keys = array('baz');
    // 	      // Loop through our $keys
    // 	      foreach($keys as $key)
    // 	      {
    // 	        $value = $row[$key]; //$value=baz_a;
    
    
    // 	        if (!isset($last)) // First $key only
    // 	        {
    // 	            if (!isset($out[$value])) $out[$value] = Array();
    // 	            echo "<B>isset out--{$value}--</B>";
    // 	            $last =& $out; // Bind $last to $out
    // 	            //$out['baz_a'] = array();
    // 	            //$last['baz_a'] = array();
    // 	        }
    // 	        else // Second and subsequent $key....
    // 	        {
    // 	            if (!isset($last[$value])) $last[$value] = Array();
    // 	            echo "<B>isset last--{$value}--</B>";
    // 	        }
    
    // 	        // Bind $last to one dimension 'deeper'.
    // 	        // First lap: was &$out, now &$out[...]
    // 	        // Second lap: was &$out[...], now &$out[...][...]
    // 	        // Third lap:  was &$out[...][...], now &$out[...][...][...]
    // 	        // (etc.)
    
    // 	        $last =& $last[$value]; //这句不太好理解
    // 	        //$last = & $last[$value]; //就是给$last重新引用一个空的数组值
    
    
    // 	        //var_dump($last);
    // 	        //echo "***";
    
    // 	      }
    
    
    //           //如果$last存在 
    // 	      if (isset($last))
    // 	      {
    // 	        // At this point, copy the $row into our output array
    // 	        if ($dupl)  //如果$dupl为true	        
    // 	            $last[$cx] = $row; // Keep previous
    // 	        else       
    // 	            $last = $row; // Overwrite previous
    // 	      }
    // 	      unset($last); // Break the reference
    // 	      //清空last这个副本内容
    // 	    }
    // 	    else return NULL;
    // 	    //echo "<BR>===================================<BR>";
    // 	    //echo "<BR>===================================<BR>";
    // 	        var_dump($out);
    // 	        echo "<BR>******************************\n";
    // 	        echo "<BR>******************************<BR><BR>";
    
    //     }
    //     // Done
    //     return $out;
    // }
    
    // // A sample result set to test the function with
    // $data = Array(Array('name' => 'row 1', 'foo' => 'foo_a', 'bar' => 'bar_a', 'baz' => 'baz_a'),
    //               Array('name' => 'row 2', 'foo' => 'foo_a', 'bar' => 'bar_a', 'baz' => 'baz_b'),
    //               Array('name' => 'row 3', 'foo' => 'foo_a', 'bar' => 'bar_b', 'baz' => 'baz_c'),
    //               Array('name' => 'row 4', 'foo' => 'foo_b', 'bar' => 'bar_c', 'baz' => 'baz_d')
    //               ); 
    
    // // First, let's key it by one column (result: two-dimensional array)
    // print_r(array_key_by($data, 'baz'));
    // echo "<BR>=====<BR>";
    // echo "<BR>=====<BR>";
    
    
    // // Or, key it by two columns (result: 3-dimensional array)
    // print_r(array_key_by($data, Array('baz', 'bar')));
    // echo "<BR>=====<BR>";
    // echo "<BR>=====<BR>";
    
    
    // // We could also key it by three columns (result: 4-dimensional array)
    // print_r(array_key_by($data, Array('baz', 'bar', 'foo')));
    // echo "<BR>=====<BR>";
    // echo "<BR>=====<BR>";
    
    
    
    
    /************************************************
    function array_key_by($data, $keys, $dupl=false)
    {
    
    	if(!is_array($data)) return null;
    
    	if(is_string($keys) or is_integer($keys)) 
    		 $keys = array($keys);
        elseif(!is_array($keys))
        	 return null;
        $out = array();    
        foreach ($data as $cx => $row)
        {
        	 if(is_array($row))
        	 {
                 foreach($keys as $key)
                 {
                       $value =  $row[$key];
                       if(!isset($last)){
                       	   if(!isset($out[$value])) $out[$value] = array();
                       	   $last = & $out;
                       }else{
                       	   if(!isset($last[$value])) $last[$value] = array();
                       }
                       echo "<BR>******<BR>";
                       var_dump($last[$value]);
                       echo "<BR>******<BR>";
    
                       $last= & $last[$value]; //将last指向一个自己的一个地址
                 }  
                 if(isset($last))
                 {
                 	 if($dupl)
                 	 {
                 	 	$last[$cx] = $row; //保存
                 	 }else
                 	    $last = $row; //保存
                 }
                 unset($last);//删除last的指向数值的地址
        	 }else
        	     return null;
        }	
        return $out;
    }
    $data = Array(Array('name' => 'row 1', 'foo' => 'foo_a', 'bar' => 'bar_a', 'baz' => 'baz_a'),
                  Array('name' => 'row 2', 'foo' => 'foo_a', 'bar' => 'bar_a', 'baz' => 'baz_b'),
                  Array('name' => 'row 3', 'foo' => 'foo_a', 'bar' => 'bar_b', 'baz' => 'baz_c'),
                  Array('name' => 'row 4', 'foo' => 'foo_b', 'bar' => 'bar_c', 'baz' => 'baz_d')
                  ); 
    
    // First, let's key it by one column (result: two-dimensional array)
    print_r(array_key_by($data, 'baz'));
    echo "<BR><BR><BR>";
    // Or, key it by two columns (result: 3-dimensional array)
    print_r(array_key_by($data, Array('baz', 'bar')));
    echo "<BR><BR><BR>";
    
    // We could also key it by three columns (result: 4-dimensional array)
    print_r(array_key_by($data, Array('baz', 'bar', 'foo')));
    echo "<BR><BR><BR>";
    ************************************************************/
    
    /**********************************************************
    class reftest
    {
        public $a = 1;
        public $b = 1;
    
        public function reftest1()
        {
             $c = & $this->a;
             $c++;
        }
    
        public function reftest2()
        {
              $c = & $this->b;
              $c++;
        }
    }
    $reftest =  new reftest;
    $reftest->reftest1();
    $reftest->reftest2();
    echo $reftest->a."<BR>";
    echo $reftest->b;
    **********************************************************/
    
    
    /**********************************************************
    class foo
    {
        protected $name;
    
        function __construct($str)
        {
             $this->name = $str;
        }
         
        function __toString()
        {
             return "my name is ".$this->name." and i Live in ".__CLASS__.".\n";
        } 
    
        function setName($str)
        {
              $this->name = $str;
        }
    }
    
    class MasterOne
    {
           protected $foo;
    
           function __construct($f)
           {
               $this->foo = $f;
           }
    
           function __tostring()
           {
               return "master ".__CLASS__." | foo:".$this->foo."\n";
           }
    
           function setFooName($str)
           {
               $this->foo->setName($str);
           }
    }
    
    class MasterTwo
    {
           protected $foo;
           function __construct($f)
           {
               $this->foo = $f;
           }
    
           function __tostring()
           {
               return "master ".__CLASS__." | foo:".$this->foo."\n";
           }
    
           function setFooName($str)
           {
               $this->foo->setName($str);
           }      
    }
    
    $bar = new foo('bar');
    echo $bar; //bar
    echo "<BR><BR>";
    
    
    $baz = & $bar;
    echo $bar; //bar
    echo "<BR><BR>";
    
    
    $m1 = new MasterOne($bar);
    $m2 = new MasterTwo($bar);
    echo $m1;
    echo "<BR><BR>";
    echo $m2;
    echo "<BR><BR>";
    
    
    $bar->setName("baz");
    echo $bar;
    echo "<BR><BR>";
    echo $baz;
    echo "<BR><BR>";
    
    echo $m1;
    echo "<BR><BR>";
    echo $m2;
    echo "<BR><BR>";
    
    
    $m2->setFooName("MasterTwo Foo");
    echo $m1;
    echo "<BR><BR>";
    echo $m2;
    echo "<BR><BR>";
    
    echo $bar;
    echo "<BR><BR>";
    echo $baz;
    echo "<BR><BR>";
    **********************************************************/
    
    
    
    /**********************************************************
    function foo(&$bar)
    {
         $bar="hello\n\t"; 
         echo $bar;
    }
    foo($unset);
    echo $unset; //hello
    foo($set="set\n\t");//这里有点弄不懂样
    echo $set; //set
    **********************************************************/
    
    
    ///////////////////////////////////////////////////////////////
    //引用不是什么
    // $GLOBALS['baz'] = "xxdxxd";
    // function foo(&$val)
    // {
    //      $var = & $GLOBALS['baz'];
    // }
    // foo($bar);
    // var_dump($bar); //null
    //这将使foo函数中的$var变量在函数调用时和$bar绑定在一起
    //但接着又会重新绑定到了$GOLBALS['baz']上面,
    //不可能通过引用机制将$bar在函数调用范围内绑定到别的变量上面,因为在函数foo中并没有变量$bar(它被表示为$var,但是$var只有变量内容而没有调用符号表中的名字到值的绑定)。可以使用引用返回来引用被函数选择的变量
    
    // const int c_1 = 1, c_2 = 2;
    // int *a = &c_1;
    // int *b = &c_2;
    // void foo(int *var)
    // {
    //     var = a;
    // }
    //C的写法
    
    // $b =1; $d = 2;
    // $a = & $b;
    // $c = & $d;
    // $b = & $c;
    // echo "a={$a}\t\n";//1
    // echo "b={$b}\t\n";//2
    // echo "c={$c}\t\n";//2
    // echo "d={$d}\t\n";//2
    // $a = (&$b); //error
    
    // $a = 0;
    // $b = &$a;
    // echo "A:";var_dump($a);echo "<BR><BR>"; //int(0)
    // echo "B:";var_dump($b);echo "<BR><BR>"; //int(0)
    
    // unset($b); //这里并不是直接释放$a所指向的地址,而只是释放$b这个变量
    // echo "*******************************";
    // echo "A:";var_dump($a);echo "<BR><BR>";  //int(0)
    // echo "B:";var_dump($b);echo "<BR><BR>";  //null 
    // //所有是跟指针,也就是C里面的区别
    
    // $a = 4;
    // $b = &$a;
    // $c = &$b;
    // echo "{$a}-{$b}-{$c}<BR>";
    // echo $a-$b-$c; //-4(4-4-4)
    // echo "<BR>";
    
    // $c = 5;
    // echo "{$a}-{$b}-{$c}<BR>";
    // echo $a-$b-$c; //-5(5-5-5)
    // echo "<BR>";
    
    
    // unset($a);
    // $c = 6;
    // echo "{$a}-{$b}-{$c}<BR>";
    // echo $a - $b - $c; //-10 (0-6-6)
    
    
    // class Dog
    // {
    //     var $Name;
    
    //     function Dog($name)
    //     {
    //         $this->Name = $name;
    //     }
    
    //     public function GetName()
    //     {
    //         return $this->Name;
    //     }
    // }
    
    // $bar = new Dog('spot');
    // function foo(&$val)
    // {
    //      $var = new Dog("Gypsy");
    // }
    // foo($bar);
    // echo $bar->GetName(); //spot
    
    
    
    // $a = 'eh';
    // $b = & $a;// $b == 'eh'
    // $c = & $b;// $c == 'eh'
    // $d = 'meh';
    
    // echo "\$a = $a\n"; //eh
    // echo "\$b = $b\n"; //eh
    // echo "\$c = $c\n"; //eh
    // echo "\$d = $d\n"; //meh
    
    // //$c = & $d ;
    // //$c = "meh"; //这样又是不同的
    // echo "\n";
    // echo "\$a = $a\n"; //eh
    // echo "\$b = $b\n"; //eh
    // echo "\$c = $c\n"; //meh
    // echo "\$d = $d\n"; //meh
    
    
    
    // unset($a);
    // unset($b);
    // $a[1]=1;
    // $a[2]=&$a[1]; //$a[2]=指向了1数值地址
    // $b=$a;
    // $b[2]=7; //这样修改,等于同时修改了$a[2]所指向的值
    // //$a[2]所指向的值也是$a[1]所指向的值
    // print_r($a);
    // echo "<BR><BR>";
    // print_r($b);
    
    
    // class my
    // {
    //     var $value;
    
    //     function get1(&$ref)
    //     {
    //          $ref[] = &$this; //把自己的引用给了$ref的数组
    //     }
    
    //     function get2(&$ref)
    //     {
    //          $ref[] = &$this; //把自己的引用给了$ref的数组
    //     }
    
    //     function get3(&$ref)
    //     {
    //          $ref[] = $this; //这里只是一个copy不起做用
    //     }
    // }
    
    // $m = new my;
    // $m->value = 'foo';
    // $m->get1($ref=array());
    
    // $m1 = & $ref[0];
    // $m1->value = 'bar';
    
    // echo "m:".get_class($m).'->value='.$m->value."<BR><BR>";
    // echo "m1:".get_class($m1).'->value='.$m1->value."<BR><BR>";
    
    // $m->value = 'foo';
    // $m->get2($m2);
    //$m2->value = 'bar'; //这样是错误的 $m2是一个数组,并不是一个对像
    //$m2[0]->value = 'bar';
    // $m2 = &$m2[0];
    // $m2->value = 'bar';
    // echo "m:".get_class($m).'->value='.$m->value."<BR><BR>";
    // echo "m2:".get_class($m2).'->value='.$m2->value."<BR><BR>";
    
    
    
    //它被设置为一个副本becuase不起作用
    // $m->value = 'foo';
    // $m->get3($m3);
    // $m3[0]->value = 'bar';
    // echo "m:".get_class($m).'->value='.$m->value."<BR><BR>"; //my->value=bar
    // echo "m3:".get_class($m3[0]).'->value='.$m3[0]->value."<BR><BR>"; //my->value=bar
    
    
        // $b = 1; 
        // $a =& $b; 
    
        // print("<pre>"); 
        // print("\$a === \$b: ".(($a === $b) ? "ok" : "failed")."\n"); //ok
        // print("unsetting \$a...\n");  
        // unset($a); 
        // print("now \$a is ".(isset($a) ? "set" : "unset")." and \$b is ".(isset($b) ? "set" : "unset")."\n"); 
        // //unset set
        // print("</pre>"); 
    
    
        // $b = 1; 
        // $a =& $b; 
    
        // print("<pre>"); 
        // print("\$a === \$b: ".(($a === $b) ? "ok" : "failed")."\n"); //ok
        // print("unsetting \$b...\n"); 
        // unset($b); 
        // print("now \$a is ".(isset($a) ? "set" : "unset")." and \$b is ".(isset($b) ? "set" : "unset")."\n"); 
        // //set unset
        // print("</pre>"); 
    
    
    $a = 3; $b =& $a;
    function foo (&$c) { $c = new stdClass(); }
    function bar () { return new stdClass(); }
    function &fum () { return new stdClass(); }
    
    
    if (!is_object($a)) { echo "\$a does not initially refer to an object<BR>"; }
    
    foo($b); //$b已经是对象了
    echo "\$b ", ($a === $b)? "has not": "has", " been re-bound by foo<BR>";
    if (is_object($a)) { echo "\$a now contains an object identifier<BR>"; }
    //$a也是对象了
    
    
     $b =& bar(); //has not
     echo "\$b ", ($a === $b)? "has not": "has", " been re-bound by bar<BR>";
     
     $b =& fum();//has 因为这里返回的是一个引用,而不是一个对像
     //function &fun(){ ....}
     echo "\$b ", ($a === $b)? "has not": "has", " been re-bound by fum<BR>";
    
    ?>
    

      

  • 相关阅读:
    day22 os模块
    开始 Dojo 开发
    Java 多线程编程
    Oracle 中常用数据字典大总结
    使用Java API的5个技巧
    Java 守护线程概述
    给Java新手的一些建议——Java知识点归纳(Java基础部分)
    消息中间件收录集
    2017年Java面试题整理
    Java 9 新特性快速预览
  • 原文地址:https://www.cnblogs.com/xiangxiaodong/p/2916403.html
Copyright © 2020-2023  润新知