引用定位

许多 PHP 的语法结构是通过引用机制实现的,所以上述有关引用绑定的一切也都适用于这些结构。一些结构,例如引用传递和返回,已经在上面提到了。其它使用引用的结构有:

global 引用

当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:

<?php
$var
=& $GLOBALS["var"];
?>

这意味着,例如,unset $var 不会 unset 全局变量。

$this

在一个对象的方法中,$this 永远是调用它的对象的引用。


add a note add a note User Contributed Notes
ludvig dot ericson at gmail dot com
28-Feb-2006 07:36
For the sake of clarity:

$this is a PSEUDO VARIABLE - thus not a real variable. ZE treats is in other ways then normal variables, and that means that some advanced variable-things won't work on it (for obvious reasons):

<?php
class Test {
   var
$monkeys = 0;
  
   function
doFoobar() {
      
$var = "this";
       $
$var->monkeys++; // Will fail on this line.
  
}
}

$obj = new Test;
$obj->doFoobar(); // Will fail in this call.
var_dump($obj->monkeys); // Will return int(0) if it even reaches here.
?>
ksamvel at gmail dot com
11-Feb-2006 01:02
One may check reference to any object by simple operator==( object). Example:

  class A {}

  $oA1 = new A();

  $roA = & $oA1;

  echo "roA and oA1 are " . ( $roA == $oA1 ? "same" : "not same") . "<br>";

  $oA2 = new A();
  $roA = & $roA2;

  echo "roA and oA1 are " . ( $roA == $oA1 ? "same" : "not same") . "<br>";

Output:

roA and oA1 are same
roA and oA1 are not same

Current technique might be useful for caching in objects when inheritance is used and only base part of extended class should be copied (analog of C++: oB = oA):

class A {
  /* Any function changing state of A should set $bChanged to true */
  public function isChanged() { return $this->bChanged; }
  private $bChanged;
  //...
}

class B extends A {
// ...
  public function set( &$roObj) {
   if( $roObj instanceof A) {
     if( $this->roAObj == $roObj &&
         $roObj->isChanged()) {
       /* Object was not changed do not need to copy A part of B */
     } else {
       /* Copy A part of B */
       $this->roAObj = &$roObj;
     }
   }
  }

  private $roAObj;
}
Sergio Santana: ssantana at tlaloc dot imta dot mx
17-Dec-2005 12:41
*** WARNING about OBJECTS TRICKY REFERENCES ***
-----------------------------------------------
The use of references in the context of classes
and objects, though well defined in the documentation,
is somehow tricky, so one must be very careful when
using objects. Let's examine the following two
examples:

<?php
 
class y {
  
public $d;
  }
 
 
$A = new y;
 
$A->d = 18;
  echo
"Object \$A before operation:\n";
 
var_dump($A);
 
 
$B = $A; // This is not an explicit (=&) reference assignment,
           // however, $A and $B refer to the same instance
           // though they are not equivalent names
 
$C =& $A; // Explicit reference assignment, $A and $C refer to
           // the same instance and they have become equivalent
           // names of the same instance
 
 
$B->d = 1234;
 
  echo
"\nObject \$B after operation:\n";
 
var_dump($B);
  echo
"\nObject \$A implicitly modified after operation:\n";
 
var_dump($A);
  echo
"\nObject \$C implicitly modified after operation:\n";
 
var_dump($C);
 
 
// Let's make $A refer to another instance
 
$A = new y;
 
$A->d = 25200;
  echo
"\nObject \$B after \$A modification:\n";
 
var_dump($B); // $B doesn't change
 
echo "\nObject \$A after \$A modification:\n";
 
var_dump($A);
  echo
"\nObject \$C implicitly modified after \$A modification:\n";
 
var_dump($C); // $C changes as $A changes
?>

Thus, note the difference between assignments $X = $Y and $X =& $Y.
When $Y is anything but an object instance, the first assignment means
that $X will hold an independent copy of $Y, and the second, means that
$X and $Y will refer to the same thing, so they are tight together until
either $X or $Y is forced to refer to another thing. However, when $Y
happens to be an object instance, the semantic of $X = $Y changes and
becomes only slightly different to that of $X =& $Y, since in both
cases $X and $Y become references to the same object. See what this
example outputs:

Object $A before operation:
object(y)#1 (1) {
  ["d"]=>
  int(18)
}

Object $B after operation:
object(y)#1 (1) {
  ["d"]=>
  int(1234)
}

Object $A implicitly modified after operation:
object(y)#1 (1) {
  ["d"]=>
  int(1234)
}

Object $C implicitly modified after operation:
object(y)#1 (1) {
  ["d"]=>
  int(1234)
}

Object $B after $A modification:
object(y)#1 (1) {
  ["d"]=>
  int(1234)
}

Object $A after $A modification:
object(y)#2 (1) {
  ["d"]=>
  int(25200)
}

Object $C implicitly modified after $A modification:
object(y)#2 (1) {
  ["d"]=>
  int(25200)
}

Let's review a SECOND EXAMPLE:
<?php
 
class yy {
  
public $d;
   function
yy($x) {
    
$this->d = $x;
   }
  }

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

 
$A = new yy(3);
 
var_dump($A);
 
modify($A);
 
var_dump($A);
?>

Although, in general, a formal argument declared
as $v in the function 'modify' shown above, implies
that the actual argument $A, passed when calling
the function, is not modified, this is not the
case when $A is an object instance. See what the
example code outputs when executed:

object(yy)#3 (1) {
  ["d"]=>
  int(3)
}
object(yy)#3 (1) {
  ["d"]=>
  int(1225)
}
Sergio Santana: ssantana at tlaloc dot imta dot mx
11-Aug-2005 12:30
Sometimes an object's method returning a reference to itself is required. Here is a way to code it:

<?php
class MyClass {
 
public $datum;
 
public $other;
 
  function &
MyRef($d) { // the method
  
$this->datum = $d;
   return
$this; // returns the reference
 
}
}

$a = new MyClass;
$b = $a->MyRef(25); // creates the reference

echo "This is object \$a: \n";
print_r($a);
echo
"This is object \$b: \n";
print_r($b);

$b->other = 50;

echo
"This is object \$a, modified" .
    
" indirectly by modifying ref \$b: \n";
print_r($a);
?>

This code outputs:
This is object $a:
MyClass Object
(
   [datum] => 25
   [other] =>
)
This is object $b:
MyClass Object
(
   [datum] => 25
   [other] =>
)
This is object $a, modified indirectly by modifying ref $b:
MyClass Object
(
   [datum] => 25
   [other] => 50
)