Saturday, March 24, 2007

Returning References

Returning by-reference is useful when you want to use a function to find which variable a reference should be bound to. Do not use return-by-reference to increase performance, the engine is smart enough to optimize this on its own. Only return references when you have a valid technical reason to do it! To return references, use this syntax:


<?php
function &find_var($param)
{
/* ...code... */
return $found_var;
}

$foo =& find_var($bar);
$foo->x = 2;
?>

In this example, the property of the object returned by the find_var function would be set, not the copy, as it would be without using reference syntax.
Note: Unlike parameter passing, here you have to use & in both places - to indicate that you return by-reference, not a copy as usual, and to indicate that reference binding, rather than usual assignment, should be done for $foo.

Note: If you try to return a reference from a function with the syntax: return ($found_var); this will not work as you are attempting to return the result of an expression, and not a variable, by reference. You can only return variables by reference from a function - nothing else. E_NOTICE error is issued since PHP 4.4.0 and PHP 5.1.0 if the code tries to return a dynamic expression or a result of the new operator.

While trying to create a function to return Database connection objects, it took me a while to get this right:

<?php

class TestClass
{
var $thisVar = 0;

function TestClass($value)
{
$this->thisVar = $value;
}

function &getTestClass($value)
{
static $classes;

if (!isset($classes[$value]))
{
$classes[$value] = new TestClass($value);
}

return $classes[$value];
}
}

echo "<pre>";

echo "Getting class1 with a value of 432\n";
$class1 =& TestClass::getTestClass(432);
echo "Value is: " . $class1->thisVar . "\n";

echo "Getting class2 with a value of 342\n";
$class2 =& TestClass::getTestClass(342);
echo "Value is: " . $class2->thisVar . "\n";

echo "Getting class3 with the same value of 432\n";
$class3 =& TestClass::getTestClass(432);
echo "Value is: " . $class3->thisVar . "\n";

echo "Changing the value of class1 to 3425, which should also change class3\n";
$class1->thisVar = 3425;

echo "Now checking value of class3: " . $class3->thisVar . "\n";

?>

Which outputs:

Getting class1 with a value of 432
Value is: 432
Getting class2 with a value of 342
Value is: 342
Getting class3 with the same value of 432
Value is: 432
Changing the value of class1 to 3425, which should also change class3
Now checking value of class3: 3425

Note that PHP syntax is different from C/C++ in that you must use the & operator in BOTH places, as stated by the manual. It took me a while to figure this out.

No comments :