引用定位
///////////////////////////////////////////////////// //@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