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>";

?>

  

原文地址:https://www.cnblogs.com/xiangxiaodong/p/2916403.html