Showing posts with label reference. Show all posts
Showing posts with label reference. Show all posts

Friday, June 5, 2009

Object references, assignment and as function arguments

As of PHP5, objects are treated REFERENCE ! (same behaviour as C++ and Java)

1) assignment from an objects to another copies the reference, not the content !!
What is a reference ? it's a variabile/object that ONLY contains the pointer to the effective object in the memory. As I said in a previous post, the assigment instruction copy ONLY the value (pointer) of the object-pointer, it doesn't duplicate the content (members) of the class !
Let's demonstrate with an example, using the unset() function

class A { public $foo = 1; }
$a = new A;
$aRef = $a;
unset($aRef ); //delete ONLY the object-pointer !
print $a->foo; //print 1. This is the proof that $aRef is only a pointer

$aRef = $a;
unset($aRef ->foo); //through the object-pointer $c, it delete the real content !!
print $a->foo; //Notice: Undefined property !! This is the proof that $aRef is not a copy !!

2) objects are passed to functions by REFERENCE !

class A { public $foo = 1; }
$a = new A;
function foo($obj) {
$obj->foo = 2;
unset($obj); // delete local reference (that is a copy), no problem !
}
foo($a);
echo $a->foo; //2 ! this is the proof that the argument is passed as reference (the function doesn't return any value !) and not as a copy (the value outside the function is changed!)


Note 1: arrays are passed by copy, unless the function declare the argument as reference with "&"
function arrayDeleteFirst(&$ar) { unset($ar[0]); }

Note2: references work with variables as well
$a = 1;
$b = &$a;
$b = 2;
unset($b); //no problem. It deletes the reference, not the variabile pointed !
print $a; //2

Thursday, June 4, 2009

PHP5: object references, object cloning and __clone()

Let's make a simple class with a value (default=1), set and get methods

class Obj
{
private $var=1;
public function
setVal($var) { $this->var = $var; }
public function getVal() { return $this->var; }
}

Following, another class that includes the previous one (Or better, it includes a reference to the previous class, and the object will be instantiated by the constructor)

class A
{
private $obj; //reference to the previous class
private $i=1; //internal variabile
public function __construct() { $this->obj = new Obj(); }
//set the private properties and the val of the internal object !
public function
setAll($v) { $this->obj->setVal($v); $this->i =$v; }
public function
getObj() { return $this->obj->getVal(); }
public function
getI() { return $this->i; }
function
__clone()
{
$this->obj = clone $this->obj;
}
}

OBJECT ASSIGN (IT'S NOT A COPY)
Now we instantiate a class and assign its reference to other variables

$a = new A();
$aRef = &$a; // REFERENCE
$aCopy = $a; // REFERENCE as well, the same as before!!!

$a->setAll(2);

print
$aRef-> getObj(); //2
print $aRef->getI();//2
print $aCopy-> getObj();//2
print $aCopy->getI();//2

CLONING
to copy all the elements of an object to another reference/variabile, you must clone it, using "clone" keyword.
$a = new A();
$aClone = clone $a; //CLONE
$a->setAll(2); //the cloned object ($aClone) won't be modified !

print
$aClone->getI(); // "1"
print $aClone->getObj(); //"1"
thanks to the overriding __clone() method,
otherwise "2"

 

PHP and tips|PHP