I had a Java developer new to PHP ask me this question the other day, so I thought I'd document the answer here.
Question: are PHP variables passed by value or by reference?
I had a Java developer new to PHP ask me this question the other day, so I thought I'd document the answer here.
Question: are PHP variables passed by value or by reference?
PHP variables are assigned by value, passed to functions by value, and when containing/representing objects are passed by reference. You can force variables to pass by reference using an &
Assigned by value/reference example:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
would output "var1: test, var2: final test, var3: final test".
Passed by value/reference exampe:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
would output: "var1: foo, var2 BAR".
Object passed by reference exampe:
class Foo{
public $var1;
function __construct(){
$this->var1 = "foo";
}
public function printFoo(){
print $this->var1;
}
}
$foo = new Foo();
changeFoo($foo);
$foo->printFoo();
function changeFoo($foo){
$foo->var1 = "FOO";
}
Would output: "FOO"
(that last example could be better probably...)
Depends on the version, 4 is by value, 5 is by reference.
Can you point to some documentation that says that? from everything I've seen, that's not the case...
It's by value according to the PHP Documentation.
By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.
To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition.
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
@Karl
In PHP5 variables are by default passed by value and objects are by default passed by reference.
Either can be optionally passed by reference using the & operator.
However, most older PHP functions will not alter a primitive even if you pass a reference...
$str = "hello world";
echo $str; // hello world
echo strrev($str); // dlrow olleh
strrev( &$str ); // ! Warning is issued
echo $str; // hello world
$str = strrev($str);
echo $str; // dlrow olleh
If you do try to pass a value as a reference it will throw a warning. It is up to the function to decide to work on the value or reference.
http://www.php.net/manual/en/migration5.oop.php
In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or passed as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).
Variables containing primitive types are passed by value in PHP5. Variables containing objects are passed by reference. There's quite an interesting article from Linux Journal from 2006 which mentions this and other OO differences between 4 and 5.
It seems a lot of people get confused by the way objects are passed to functions and what pass by reference means. Object variables are still passed by value, its just the value that is passed in PHP5 is a reference handle. As proof:
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
Outputs:
a b
To pass by reference means we can modify the variables that are seen by the caller. Which clearly the code above does not do. We need to change swap to:
<?php
function swap(&$x, &$y) {
$tmp = $x;
$x = $y;
$y = $x;
}
in order to pass by reference.
You can do it either way.
put a '&' symbol in front and the variable you are passing becomes one and the same as its origin. ie: you can pass by reference, rather than making a copy of it.
so
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
Objects are passed by reference in PHP 5 and by value in PHP 4. Variables are passed by value by default!
Read here: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
class Holder
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue( $value )
{
return $this->value = $value;
}
}
class Swap
{
public function SwapObjects( Holder $x, Holder $y )
{
$tmp = $x;
$x = $y;
$y = $tmp;
}
public function SwapValues( Holder $x, Holder $y )
{
$tmp = $x->getValue();
$x->setValue($y->getValue());
$y->setValue($tmp);
}
}
$a1 = new Holder('a');
$b1 = new Holder('b');
$a2 = new Holder('a');
$b2 = new Holder('b');
Swap::SwapValues($a1, $b1);
Swap::SwapObjects($a2, $b2);
echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
Attributes are still modifiable when not passed by reference so beware.
Output:
SwapObjects: b, a SwapValues: a, b