I want to increase $x by 1:
$x = 1;
function addOne($x) {
$x++;
return $x;
}
$x = addOne($x);
Is there a way to do this with references, so I don't need to return $x, I can just write addOne($x)?
This is what you're looking for, a by-ref parameter indicated by &.
$x = 1;
function addOne(&$x) {
$x++;
}
addOne($x);
Some notes:
By-ref parameters require that the value passed in not be a literal. Given my example above, addOne(5) would throw a fatal exception
References are not needed for objects (including stdClass objects), as all objects are passed by reference as of PHP 5.
References ARE needed for arrays, as arrays in PHP are not treated as objects
If you want a return value of a function passed by reference, you would indicate the reference on the function name (e.g. function &foo()).
More info on references: http://php.net/manual/en/language.references.php
$x = 1;
function addOne(&$x) {
$x++;
}
addOne($x);
The & sign shows that it takes the parameter by reference. So it increments $x in the function and it will also affect the $x variable in the calling scope.
See also: http://php.net/references for a quick overview about them.
Related
<?php
function sum($y) {
$y = $y + 5;
}
$x = 5;
sum($x);
echo $x;
?>
So I have this code. The questions are: What does it output? The answer: 5. How do I make it to output 10? The answer: sum(&$x).
The problem is that I don't understand why the answer to the first question is 5. When you make sum($x), shouldn't it replace the function with $x, so $x= 5+5=10? Why the answer is 5? I really don't understand. Someone explaind me something related to pointers and the adress, but I didn't understand. I never understood the concept of pointers, and I googled it and apparently there are no pointers in php, so I'm super confused. My friend said that a variable is formed of a value, and the memory adress of that value. Can someone explain me like I'm 5 years old why the answer is 5 and not 10? Please
Let's pretend $x is a piece of paper with 5 written on it.
function sum($y) {
$y = $y + 5;
}
Here $y is the value of what you have written. You add 5 to such value in your mind, but the note is left untouched.
function sum(&$y) {
$y = $y + 5;
}
With the reference operator (&$y), you pass the very paper to the function, and it overwrites what's written on it.
For primitive values like numbers, I wouldn't bother and always return the value you want:
function valuePlusFive($x) {
return $x + 5;
}
$x = 5;
$x = valuePlusFive($x);
This is not a very good explanation from theory point of view, but this should help you understand the concept:
when you declare function like this and then call it:
function ($argument) {...}
The argument you pass there is passed by value. This means that inside the scope of a function you will be working with a copy of an argument you passed. You can imagine that before the function is called the copy of argument has been made and inside the function you're working with the copy, while original remains untouched. Once the function is finished the copy is no more
However when you declare it like this:
function (&$argument) {...}
You are passing argument by reference, meaning that you are working directly with a variable you've passed. So in this case no copies are made, you took the argument from one place, put it inside the function and changed it.
In PHP, "The scope of a variable is the context within which it is defined." (according to the docs). So inside your function, $y (a copy of the value you passed in) is being operated on, but it is not returned by the function. So when the function ends, the value is no longer accessible outside the function.
If you want to pass the variable in by reference (similar to a pointer in C) then you can add a & like so:
function sum(&$y) {
$y = $y + 5;
}
Now when you call this code:
$x = 5;
sum($x);
echo $x;
it will output 10. Maybe a better way to do this would be to return a value from your function, and output that value:
function sum($y) {
return $y + 5;
}
$x = 5;
echo sum($x);
I have seen in my journey to creaitng and building some of my php applications, the & symbol within front of vars, = and class names.
I understand that these are PHP References, but the docs i have seen and looked at seem to just not explain it in a way that i understand or confusing. How can you explain the following examples that i have seen to make them more understandable.
public static function &function_name(){...}
$varname =& functioncall();
function ($var, &$var2, $var3){...}
Much appreciated
Let's say you have two functions
$a = 5;
function withReference(&$a) {
$a++;
}
function withoutReference($a) {
$a++;
}
withoutReference($a);
// $a is still 5, since your function had a local copy of $a
var_dump($a);
withReference($a);
// $a is now 6, you changed $a outside of function scope
var_dump($a);
So, passing argument by reference allows function to modify it outside of the function scope.
Now second example.
You have a function which returns a reference
class References {
public $a = 5;
public function &getA() {
return $this->a;
}
}
$references = new References;
// let's do regular assignment
$a = $references->getA();
$a++;
// you get 5, $a++ had no effect on $a from the class
var_dump($references->getA());
// now let's do reference assignment
$a = &$references->getA();
$a++;
// $a is the same as $reference->a, so now you will get 6
var_dump($references->getA());
// a little bit different
$references->a++;
// since $a is the same as $reference->a, you will get 7
var_dump($a);
Reference functions
$name = 'alfa';
$address = 'street';
//declaring the function with the $ tells PHP that the function will
//return the reference to the value, and not the value itself
function &function_name($what){
//we need to access some previous declared variables
GLOBAL $name,$address;//or at function declaration (use) keyword
if ($what == 'name')
return $name;
else
return $address;
}
//now we "link" the $search variable and the $name one with the same value
$search =& function_name('name');
//we can use the result as value, not as reference too
$other_search = function_name('name');
//any change on this reference will affect the "$name" too
$search = 'new_name';
var_dump($search,$name,$other_search);
//will output string 'new_name' (length=8)string 'new_name' (length=8)string 'alfa' (length=4)
Usually you use the method with Objects that implemented the same interface, and you want to choose the object you want to work with next.
Passing by reference:
function ($var, &$var2, $var3){...}
I'm sure you saw the examples, so I'll just explain how and when to use it.
The basic scenario is when do you have a big logic that you want to apply to a current object/data, and you do not wish to make more copies of it (in memory).
Hope this helps.
In PHP 5, are you required to use the & modifier to pass by reference? For example,
class People() { }
$p = new People();
function one($a) { $a = null; }
function two(&$a) { $a = null; )
In PHP4 you needed the & modifier to maintain reference after a change had been made, but I'm confused on the topics I have read regarding PHP5's automatic use of pass-by-reference, except when explicity cloning the object.
In PHP5, is the & modifier required to pass by reference for all types of objects (variables, classes, arrays, ...)?
are you required to use the & modifier to pass-by-reference?
Technically/semantically, the answer is yes, even with objects. This is because there are two ways to pass/assign an object: by reference or by identifier. When a function declaration contains an &, as in:
function func(&$obj) {}
The argument will be passed by reference, no matter what. If you declare without the &
function func($obj) {}
Everything will be passed by value, with the exception of objects and resources, which will then be passed via identifier. What's an identifier? Well, you can think of it as a reference to a reference. Take the following example:
class A
{
public $v = 1;
}
function change($obj)
{
$obj->v = 2;
}
function makezero($obj)
{
$obj = 0;
}
$a = new A();
change($a);
var_dump($a);
/*
output:
object(A)#1 (1) {
["v"]=>
int(2)
}
*/
makezero($a);
var_dump($a);
/*
output (same as before):
object(A)#1 (1) {
["v"]=>
int(2)
}
*/
So why doesn't $a suddenly become an integer after passing it to makezero? It's because we only overwrote the identifier. If we had passed by reference:
function makezero(&$obj)
{
$obj = 0;
}
makezero($a);
var_dump($a);
/*
output:
int(0)
*/
Now $a is an integer. So, there is a difference between passing via identifier and passing via reference.
Objects will pass-by-reference. Built in types will be pass-by-value (copied);
What is happening behind the scenes is that when you pass in a variable that holds an object, it's a reference to the object. So the variable itself is copied, but it still references the same object. So, essentially there are two variable, but both are pointing to the same object. Changes made to objects inside a function will persist.
In the case of the code that you have there (first you need $ even with &):
$original = new Object();
one($original); //$original unaffected
two($original); //$original will now be null
function one($a) { $a = null; } //This one has no impact on your original variable, it will still point to the object
function two(&$a) { $a = null; ) //This one will set your original variable to null, you'll lose the reference to the object.
You're using it wrong. The $ sign is compulsory for any variable. It should be:
http://php.net/manual/en/language.references.pass.php
function foo(&$a)
{
$a=null;
}
foo($a);
To return a reference, use
function &bar($a){
$a=5;
return $a
}
In objects and arrays, a reference to the object is copied as the formal parameter, any equality operations on two objects is a reference exchange.
$a=new People();
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a
function goo($obj){
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e
}
$e=new People();
goo($e);
Please see this code:
function addCounter(&$userInfoArray) {
$userInfoArray['counter']++;
return $userInfoArray['counter'];
}
$userInfoArray = array('id' => 'foo', 'name' => 'fooName', 'counter' => 10);
$nowCounter = addCounter($userInfoArray);
echo($userInfoArray['counter']);
This will show 11.
But! If you remove "&"operator in the function parameter, the result will be 10.
What's going on?
The & operator tells PHP not to copy the array when passing it to the function. Instead, a reference to the array is passed into the function, thus the function modifies the original array instead of a copy.
Just look at this minimal example:
<?php
function foo($a) { $a++; }
function bar(&$a) { $a++; }
$x = 1;
foo($x);
echo "$x\n";
bar($x);
echo "$x\n";
?>
Here, the output is:
1
2
– the call to foo didn’t modify $x. The call to bar, on the other hand, did.
Here the & character means that the variable is passed by reference, instead of by value. The difference between the two is that if you pass by reference, any changes made to the variable are made to the original also.
function do_a_thing_v ($a) {
$a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 5
function do_a_thing_r (&$a) {
$a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 6
When using the ampersand prior to a variable in a function call, it associates with the original variable itself. With that, the code you posted is saying that it will add 1 to the counter of the original array. Without the ampersand, it takes a copy of the data and adds to it, then returns the new counter of 11. The old array still remains intact at 10 and the new counter variable returned turns into 11.
http://www.phpreferencebook.com/samples/php-pass-by-reference/
is a good example.
Maybe I can add to the other answers that, if it is an object, then it is not "the object passed as value", but it is "the object's reference is passed as a value" (although I am asking what the difference is between "the object is passed by reference" vs "the object's reference is passed by value" in the comments). An array is passed by value by default.
Information: Objects and references
Example:
class Foo {
public $a = 10;
}
function add($obj) {
$obj->a++;
}
$foo = new Foo();
echo $foo->a, "\n";
add($foo);
echo $foo->a, "\n";
Result:
$ php try.php
10
11
Returning by reference is useful when
you want to use a function to find to
which variable a reference should be
bound. Do not use return-by-reference
to increase performance. The engine
will automatically optimize this on
its own. Only return references when
you have a valid technical reason to
do so.
whats does the bolded mean?
does it refer to something like
public function &getHellos() {
$sql = 'SELECT id, greeting FROM #__hello';
$data = $this->_getList($sql);
return $data;
}
where i am not binding to any variable?
We return by reference when we want the function GetRef() to decide which variable, $foo or $bar, the reference $foo_or_bar should be bound:
$foo = "foo";
$bar = "bar";
function &GetRef(){
global $foo, $bar;
if(rand(0, 1) === 1){
return $foo;
}else{
return $bar;
}
}
$foo_or_bar =& GetRef();
$foo_or_bar = 'some other value';
var_dump($foo); // either one of this will be 'some other value'
var_dump($bar); // either one of this will be 'some other value'
Derick Ethans also elaborated on this in "References in PHP: An In-Depth Look":
This [returning by reference] is useful, for example, if you want to
select a variable for modification with a function, such as selecting
an array element or a node in a tree structure.
Example code demonstrating selecting array element via return-by-reference:
function &SelectArrayElement(&$array, $key){
return $array[$key];
}
$array = array(0, 1, 2);
$element =& SelectArrayElement($array, 0);
$element = 10;
var_dump($array); // array(10, 1, 2)
Na. You can't pass a reference to a function name.
When passing a variable by reference, if you change it's value in your function, it's value will also be changed outside of the function.
For example :
function test(&$var) {
$var = strtolower($var);
}
function second_test($var) {
$var = strtolower($var);
}
$var = 'PHP';
second_test($var);
echo $var;
echo "\r\n";
test($var);
echo $var;
This will display :
PHP
php
As the second_test method doesn't have the variable passed by reference, it's updated value is only updated inside the function.
But the test method as the variable passed by reference. So it's value will be updated inside and outside of this function.
I believe it's referring to byref arguments not functions. For example this:
function doStuff(&$value1, &$value2) {
...
}
is an acceptable use of byref because the doStuff() function has to return 2 values. If it only doStuff() only needed to affect one value, it would be more elegant to have the function return it, by value, of course.
The bolded part means it's useful if you want to keep a reference to a variable, instead of the value of this variable.
The example about returning references, on php.net, explains it pretty well, IMO.