引用定位

/////////////////////////////////////////////////////
//@date: 2013-02-21
//引用定位
//许多PHP的语法结构是通过引用机制实现的,所以上述有关引用绑定的事切都适用于这些结构,一些结构,例如引用传递和返回,

//global 引用
//当用global $var 声明一个变量时实现上建立了一个全局变量的引用,也就是说和这样做是相同的
//$var = & $GLOBALS['var'];
//$this 在一个对象的方法中,$this永远是调用它的对象的引用


// $a = 1;
// $b =& $a;
// $c =2;
// $d = 3;
// $e = array($a);
// function is_reference($var){
//     $val = $GLOBALS[$var];
//     $tmpArray = array();
//     /**
//      * Add keys/values without reference
//      */
//     foreach($GLOBALS as $k => $v){
//         if(!is_array($v)){
//             $tmpArray[$k] = $v;
//         }
//     }


//     /**
//      * Change value of rest variables
//      */
//     foreach($GLOBALS as $k => $v){
        
//         if($k != 'GLOBALS' && $k != '_POST' && $k != '_GET' && $k != '_COOKIE'
//             && $k != '_FILES')
//         {
//             $is_a = !is_array($v);
//             if($k != $var  && !is_array($v)){
//               echo "var:{$var}===={$k} is_a:{$is_a}<BR><BR>";
//               echo "usleep";
//               usleep(1);
//               $GLOBALS[$k] = md5(microtime());
//               echo $GLOBALS[$k]."<BR><BR>";
//             }
//         }
//     }
//     echo $val."<BR><BR>"; //1
    
//     echo $GLOBALS[$var]."<BR><BR>";

//     $bool = $val != $GLOBALS[$var];

//     /**
//      * Restore defaults values
//      */
//     foreach($tmpArray as $k => $v){
//         $GLOBALS[$k] = $v;
//     }

//     return $bool;
// }

// var_dump(is_reference('a'));
// var_dump(is_reference('b'));
// var_dump(is_reference('c'));
// var_dump(is_reference('d'));
// // 基本理解,明天晚上重新一次



// $a = 1;
// $b = &$a;
// $c = 2;
// $d = 3;
// $e = array($a);

// function is_reference($var)
// {
//     $val = $GLOBALS[$var];
//     $tmpArray = array();

//     foreach ($GLOBALS as $k => $v) {
//         if(!is_array($v)){
//              $tmpArray[$k] = $v;
//         }
//     }


//     foreach($GLOBALS as $k=>$v)
//     {
//          if($k != "GLOBALS" && $k !="_POST" && $k !="_GET"
//            && $k != "_COOKIE" && $k !="_FILES")
//          {
//                if($k != $var && !is_array($v))
//                {
//                     usleep(1);
//                     $GLOBALS[$k] = md5(microtime()); 
//                }
//          }
//     }
//     //echo "\$var:{$var}  ".$GLOBALS[$var];
//     $bool = $val != $GLOBALS[$var];
//     foreach ($tmpArray as $key => $value) {
//          $GLOBALS[$key] = $value;
//     }
//     return $bool;
// }

// var_dump(is_reference('a'));
// echo "<BR><BR>";

// var_dump(is_reference('b'));
// echo "<BR><BR>";

// var_dump(is_reference('c'));
// echo "<BR><BR>";

// var_dump(is_reference('d'));
// echo "<BR><BR>";


//如果你要检查,如果两个变量引用对方(即指向相同的内存),你可以使用这样的功能:
// function same_type(&$var1, &$var2)
// {
//      return gettype($var1) === gettype($var2);
// }

// function is_ref(&$var1, &$var2)
// {
//      if(!same_type($var1, $var2))
//          return false;

//      $same = false;

//      //数组
//      if(is_array($var1))
//      {
//           //获取或生成一个唯一的key值
//           do{
//               $key = uniqid("is_ref_", true);
//           }while(array_key_exists($key, $var1));
           
//           if(array_key_exists($key, $var2)){
//                return false;
//           } 

//           $data = uniqid("is_ref_data_", true);
//           $var1[$key] = & $data; //设置$var1[$key]的值
//           //这里也就是如果$var1与$var2是引用关系
//           //也就是关联到同一个内存地址
//           if(array_key_exists($key, $var2)){
//                 if($var2[$key] === $data){
//                     $same = true;
//                 }
//           }
//           unset($var1[$key]);
     
//      //如果是对象
//      }elseif(is_object($var1))
//      {
//           //如果不是同一个类型,直接返回
//           //get_class返类名
//           if(get_class($var1) !== get_class($var2))
//              return false; 
//           //get_object_vars返回对象的所有属性 
//           $obj1 = array_keys(get_object_vars($var1));
//           $obj2 = array_keys(get_object_vars($var2));

//           do{
//                $key = uniqid("is_ref_",true);
//           }while(in_array($key, $obj1));

//           $data = uniqid("is_ref_", true);
//           $obj1->$key = &$data;
//           if(isset($var2->$key))
//           {
//                 if($var2->$key === $data)
//                     $same = true;
//           }
//           unset($var1->$key);
     

//      //判断是否为资源
//      }elseif(is_resource($var1))
//      {
//            if(get_resource_type($var1) !== get_resource_type($var2))
//                return false;
//            return ((string)$var1) === ((string)$var2);  
     
//      //其它情况,也就是基本数据类型的情况
//      }else{
//            if($var1 !== $var2)
//                return false;

//            do{
//                $key = uniqid("is_ref_", true);
//            }while($key === $var1);  

//            $tmp = $var1;
//            $var1 = $key;
//            $same = $var1 === $var2;
//            $var1 = $tmp;
//      } 
//      return $same; 
// }

// $a = 5;
// $b = 5;
// var_dump(is_ref($a, $b)); //false
// echo "<BR>======================<BR><BR>";

// $a = 5;
// $b = $a; //copy
// var_dump(is_ref($a, $b)); //false
// echo "<BR>======================<BR><BR>";

// $a = 5;
// $b = &$a;
// var_dump(is_ref($a, $b)); //true
// echo "<BR>======================<BR><BR>";

// $a = array();
// var_dump(is_ref($a, $a)); //true
// echo "<BR>======================<BR><BR>";

// $a[] = &$a;
// var_dump(is_ref($a, $a[0]));
// echo "<BR>======================<BR><BR>";

// $b = array(array());
// var_dump(is_ref($b,$b)); //true
// var_dump(is_ref($b, $b[0])); //false;
// echo "<BR>======================<BR><BR>";

// $b = array();
// $b[] = $b;
// var_dump(is_ref($b, $b)); //true
// var_dump(is_ref($b, $b[0]));
// var_dump(is_ref($b[0], $b[0][0]));
// echo "<BR>======================<BR><BR>";

// var_dump($a);
// var_dump($b);
// //*请注意PHP的内部行为,似乎做之前,实际上复制的变量的引用赋值!因此,你会得到一个数组,其中包含一个(不同的)递归阵列的最后一个测试用例,而不是一个数组,包含一个空数组,你可以期望。


// class Test
// {
//       var $monkeys = 0;
//       function doFoodbar()
//       {
//             $var = 'this';
//             $$var->monkeys ++; //这样操作是失败的
//             //在这条线将失败
//       }

//       function addMonkeys()
//       {
//             $this->monkeys++;
//       }
// }
// $obj = new Test;
// $obj->doFoodbar();
// var_dump($obj->monkeys);
// $obj->addMonkeys();
// echo "<BR><BR>";
// var_dump($obj->monkeys);


// class A{};

// $oA1 = new A();
// $roA = & $oA1;
// if($roA == $oA1){
//     echo "same";
// }else
//     echo "not same";
// echo "<BR><BR>";

// $oA2 = new A();
// $roA = & $roA2; //$roA2这个对像为空呢
// if($roA == $oA1)
//    echo "same";
// else 
//    echo "not same";
// echo "<BR><BR>";    


// class y{
//     public $d;
// }

// $A = new y;
// $A->d = 18;
// var_dump($A);echo "<BR><BR>";


// $B = $A;
// $C = &$A;
// $B->d = 1234;

// //这不是一个明确的(=&)引用赋值,
// //但是,$ A$ B指的同一个实例
// //虽然他们是不等价的名
// var_dump($B);echo "<BR><BR>"; //让我不能理解的怎么B也相当于引用了
// var_dump($C);echo "<BR><BR>";
// var_dump($A);echo "<BR><BR>";


// $A = new y;
// $A->d = 250;
// var_dump($B);echo "<BR><BR>"; //1234
// var_dump($C);echo "<BR><BR>"; //1234这样理解是错的,因为在上一步中
// //$C = &$A;所以这里的$C也是250
// var_dump($A);echo "<BR><BR>"; //250


// class yy
// {
//      public $d;

//      function yy($d)
//      {
//          $this->d = $x;
//      }
// }

// function modify($v)
// {
//      $v->d = 1225;
// }

// $A = new yy(3);
// var_dump($A); //3;
// modify($A);
// var_dump($A); //3 
//虽然在一般情况下,声明一个正式的参数$V在上面所示的“修改”的功能,意味着
//实际的参数$ A时,通过调用的功能,不被修改,这是不当$ A是一个对象实例。

class myClass
{
     public $datum;
     public $other;

     function &MyRef($d)
     {
         $this->datum = $d;
         return $this; //返回一个引用对象
     }
}

$a = new myClass();
$b = $a->MyRef(25);
print_r($a);echo "<BR><BR>"; //25
print_r($b);echo "<BR><BR>"; //25

$b->other =50;
print_r($a);echo "<BR><BR>"; //50
print_r($b);echo "<BR><BR>"; //50

  

posted @ 2013-02-21 22:34  简单--生活  阅读(308)  评论(0编辑  收藏  举报
简单--生活(CSDN)