This section provides a tutorial example on how to references on pass-by-value arguments. Using a reference expression as a pass-by-value argument allows you to modify the original variable in the calling code.
In the previous section, we tested on passing regular variables to functions using the pass-by-value mode.
But what will happen if we pass references to functions using the pass-by-value mode?
To find out the answer, I wrote this tutorial example script:
<?php # PassByValueWithReference.php
# Copyright (c) 2003 by Dr. Herong Yang. http://www.herongyang.com/
#
function swap($left, $right) {
$temp = $left;
$left = $right;
$right = $temp;
print(" Swapped in function: ".getString($left, $right)."\n");
}
print("\n 1. Passing two variables:\n");
$x = "Dog"; $y = "Cat";
print(" Before call: ". getString($x, $y) ."\n");
swap($x, $y);
print(" After call: ". getString($x, $y) ."\n");
print("\n 2. Passing two references:\n");
$y = "Bob"; $y = "Tom";
print(" Before call: ". getString($x, $y) ."\n");
swap(&$x, &$y);
print(" After call: ". getString($x, $y) ."\n");
print("\n 3. Passing two references in variables:\n");
$a = "One"; $b = "Two";
$x = &$a; $y = &$b;
print(" Before call: ". getString($a, $b) ."\n");
print(" Before call: ". getString($x, $y) ."\n");
swap($x, $y);
print(" After call: ". getString($a, $b) ."\n");
print(" After call: ". getString($x, $y) ."\n");
function getString($left, $right) {
if (is_scalar($left)) {
return "$left | $right";
} else {
return NULL;
}
}
?>
If you run this tutorial example, you should get:
1. Passing two variables:
Before call: Dog | Cat
Swapped in function: Cat | Dog
After call: Dog | Cat
2. Passing two references:
Before call: Dog | Tom
Swapped in function: Tom | Dog
After call: Tom | Dog
3. Passing two references in variables:
Before call: One | Two
Before call: One | Two
Swapped in function: Two | One
After call: One | Two
After call: One | Two
Do you see anything interesting in the output?
There is nothing strange in test 1. Pass-by-value on regular variables left no changes on original variables.
But in test 2, pass-by-value on references caused original variables to be swapped. I think I know why.
The swap() function received copies of references, &$x and &$y, swapping references actually swapped
the original variables, $x and $y.
But in test 3, pass-by-value on references stored in variables caused original variables un-touched.
Initially, I thought test 3 should behave like test 2. But by following the pass-by-value logic,
I think I know why it behaves differently. In the call, swap($x, $y), copies of values of $x and $y are passed.
Since $x and $y are reference variables, values of $x and $y are values of $a and $b, "One" and "Two".
So copies of "One" and "Two" are passed into the function. Of course, swapping these copies will have no impact
on original values of $a and $b (or $x and $y, since they are aliases of $a and $b).
Conclusion, If you call a function with a reference expression as a pass-by-value argument, you are equivalently
using this argument as a pass-by-reference argument. Changes on this argument inside the function will be applied
to the original variable in the calling code.