PHP References Explained - References and Functions
(Page 3 of 4 )
Using references in functions is done by adding an & before the parameter:
function inc( &$var )
{
++$var;
}
$a = 1;
inc( $a ); // $a is now 2 Unfortunately you cannot do this:
function assign( &$a )
{
$GLOBALS["a"] =& $a;
}
function retval()
{
return "abc";
}
$c = "a";
$d = "b";
assign( 4 ); // Constant cannot be passed
assign( retval() ); // No reference in return value
assign( $c == $d ); // Expression cannot be passed Also, returning a reference is done by adding an & before the function name and by referring to the function call:
function &createRef()
{
$a = "text";
return $a;
}
$b =& createRef(); // $b refers to the data of $a in the function What happens if you want a function to change the reference of a variable but not the data itself? As you might recall, it's not possible to create a reference to a reference. The clue is to use arrays. Create an array and let a specific key refer to your data, then pass the array to a function, which takes the parameter as a reference:
function refChange( &$b )
{
$c = "text";
$b["ref"] =& $c; // Changes the reference for "ref" key
}
$a = "test";
$arr = array();
$arr["ref"] =& $a;
refChange( $arr ); // Now $arr["ref"] refers to "text". Global Variables The global syntax is actually a reference too -- it creates a reference to a global variable:
function a()
{
global $glob1;
$glob2 =& $GLOBALS["glob1"];
} Now $glob1 and $glob2 refer to the same data. The limitations of using the global syntax is that you can't change what the global variable is referring to. You can only change the data it's referring. To achieve changing the reference for the global variable, you must do something like this:
function b()
{
$a = "test";
$GLOBALS["glob1"] =& $a; // Now the global variable $glob1 refers to contents of $a
} Iterating As mentioned above, PHP’s array iterator structures and functions such as foreach and each do not handle references very well. In-fact, they create a copy of each element that they iterate over. For instance, this code will not work:
$ref_arr = array();
foreach ( $arr as $item )
{
$ref_arr[] =& $item;
} When the foreach is encountered, the $ref_arr will contain references to the last element in the $arr array. The reason is that when you create the reference, you refer to the variable $item, which will contain the last item after foreach is done.
There are two ways to iterate through arrays correctly. The first only works with normal arrays, while the second works with all types of arrays. Method 1 involves using a for loop:
for ( $i = 0; $i < count( $arr ); ++$i )
{
$item =& $arr[$i];
} While method 2 uses the key and next functions:
reset( $arr ); // Restart the internal pointer
while ( ( $key = key( $arr ) ) !== null ) // fetch the current key, or null if at end
{
$item =& $arr[$key]; // Create reference to element
next( $arr ); // Advance to next key
} The second method is similar to the first, but now the key is fetched from the array instead of assuming a numerical index.
When Should References be Used? When you're passing on large text, arrays or object structures to functions or passing data through nested function calls. You should also perform benchmarking of your PHP code to find out places that need references; often using references will reduce execution time significantly.
When Should References Not be Used? When creating functions that are usually fed with constant values. PHP cannot create references to unassigned data, except for new object instances. For instance consider this example:
function doIt( &$a )
{
// Do something with $a
}
doIt( "some text" ); // Will not work
$txt = "some text";
doIt( $txt ); // Will work The latter will always work but is cumbersome when you're using these functions often.
Next: Conclusion >>
More PHP Articles
More By Jan Borsodi