I saw some function declarations like this:
function boo(&$var){
...
}
what does the & character do?
It's a pass by reference. The variable inside the function "points" to the same data as the variable from the calling context.
function foo(&$bar)
{
$bar = 1;
}
$x = 0;
foo($x);
echo $x; // 1
Basically if you change $var inside the function, it gets changed outside. For example:
$var = 2;
function f1(&$param) {
$param = 5;
}
echo $var; //outputs 2
f1($var);
echo $var; //outputs 5
It accepts a reference to a variable as the parameter.
This means that any changes that the function makes to the parameter (eg, $var = "Hi!") will affect the variable passed by the calling function.
It is pass by reference.
If you are familiar with C pointers, it is like passing a pointer to the variable.
Except there is no need to dereference it (like C).
you are passing $var as reference, meaning the actual value of $var gets updated when it is modified inside boo function
example:
function boo(&$var) {
$var = 10;
}
$var = 20;
echo $var; //gets 20
boo($var);
echo $var //gets 10
The ampersand ( & ) before a variable ( & $foo ) overrides pass by value to specify that you want to pass the variable by reference instead.
For example if you have this:
function doStuff($variable) {
$variable++;
}
$foo = 1;
doStuff($foo);
echo $foo;
// output is '1' because you passed the value, but it doesn't alter the original variable
doStuff( &$foo ); // this is deprecated and will throw notices in PHP 5.3+
echo $foo;
// output is '2' because you passed the reference and php will alter the original variable.
It works both ways.
function doStuff( &$variable) {
$variable++;
}
$foo = 1;
doStuff($foo);
echo $foo;
// output is '2' because the declaration of the function requires a reference.
If any function starts with ampersand(&), It means its call by Reference function. It will return a reference to a variable instead of the value.
function reference_function( &$total ){
$extra = $total + 10;
}
$total = 200;
reference_function($total) ;
echo $total; //OutPut 210
Related
As PHP manual states
Note: You should never use parentheses around your return variable when returning by reference, as this will not work. You can only return variables by reference, not the result of a statement. If you use return ($a); then you're not returning a variable, but the result of the expression ($a) (which is, of course, the value of $a).
I can not understand why not while the following code examples will give the same result.
The code with return $var:
<?php
function a(&$a) {
$a .= "c";
return $a;
}
$b = "b";
echo a($b);
echo $b;
?>
The code with return ($var):
<?php
function a(&$a) {
$a .= "c";
return ($a);
}
$b = "b";
echo a($b);
echo $b;
?>
The examples you show are Passing by Reference, where you pass a reference of a variable to a function. The quote from the manual is about Returning References of a variable in a function.
Just like you can't pass an expression by reference, you can't return an expression by reference, and wrapping a variable in () turns it in to an expression.
Passing a Reference
function a(&$b) { $b = 1; }
$x = 0;
a($x);
echo $x; // echos 1, because a reference to $x was changed
However a(abs($x)); or even a( ($x) ); generates:
Strict Standards: Only variables should be passed by reference
Returning a Reference
class a {
public $c = 0;
public function &b() { return $this->c; }
}
$a = new a;
$x = &$a->b();
$a->c = 1;
echo $x; // echos 1, because $x is a reference to $a->c that was changed
However, return ( $this->c ); generates:
Notice: Only variable references should be returned by reference
The example you give is not about returning references, but is an example of passing references.
function myfunc(&$arg) {
// here $arg has been passed by reference, nothing to do with the docs you quoted
}
The docs are about this:
function & myfunc($arg) {
// here you create your $result using $arg and whatever
return $result; // this will work
return ($result); // this will NOT
}
// and how you use it
$res =& myfunc(1);
You're modifying the variable, because it's passed by reference. But then you're setting it to the value that's returned by the function. That's why you're getting the same result.
When modifying a variable by reference, you don't need to return it. Your function will still have the same result if you write it like this:
function a(&$a) {
$a .= "c";
}
When you pass any value to the function, php copy the value and return a copy, not the variable you passed to the function. So if you want to change value and don't want to return anything from the function you need to declare, functions argument as reference - it means that any variable that you will pass to the function wont be copied by php and manipulation inside the function will change variable outside the function, for example:
$var = 1;
//not reference function
function notReference($argument)
{
$argument++;
}
notReference($var);
echo $var; // you will get 1
function reference(&$argument)
{
$argument++;
}
reference($var)
echo $var; // you will get 2,
Im trying to change the value of a declared variable which is outside the function in use of a function
<?php
$test = 1;
function addtest() {
$test = $test + 1;
}
addtest();
echo $test;
?>
but it seems it couldn't. only variables declared as parameters in the function only work. is there a technique for this? thanks in advance
Change the variable inside the function to a global -
function addtest() {
global $test;
$test = $test + 1;
}
There are a lot of caveats to using global variables -
your code will be harder to maintain over the long run because globals may have an undesired affect on future calculations where you might not be aware how the variable was manipulated.
if you refactor the code and the function goes away it will be detrimental because every instance of $test is tightly coupled to the code.
Here is a slight improvement and doesn't require global -
$test = 1;
function addtest($variable) {
$newValue = $variable + 1;
return $newValue;
}
echo $test; // 1
$foo = addtest($test);
echo $foo; // 2
Now you haven't had to use a global and you have manipulated $test to your liking while assigning the new value to another variable.
Not sure if this is a contrived example or not, but in this case (as in most cases) it would be extremely bad form to use global. Why not just return the results and assign the return value?
$test = 1;
function increment($val) {
return $val + 1;
}
$test = increment($test);
echo $test;
This way, if you ever need to increment any other variable besides $test, you're done already.
If you need to change multiple values and have them returned, you can return an array and use PHP's list to easily extract the contents:
function incrementMany($val1, $val2) {
return array( $val1 + 1, $val2 + 1);
}
$test1 = 1;
$test2 = 2;
list($test1, $test2) = incrementMany($test1, $test2);
echo $test1 . ', ' . $test2;
You can use func_get_args to also accept a dynamic number of arguments and return a dynamic number of results as well.
Use the global keyword.
<?php
$test = 1;
function addtest() {
global $test;
$test = $test + 1;
}
addtest();
echo $test; // 2
?>
so imagine I have this PHP code
<?php
$var = 10;
function foo($var)
{
global $var;
echo $var;
}
foo(2);
?>
The output here is 10. I want to know if there is a way to refer back to the function scope variable $var (which in my example has a value of 2).
Maybe not an exact answer but here is a way:
$var = 10;
function foo($var)
{
$array = get_defined_vars();
global $var;
echo $var;
echo $array['var'];
}
foo(2);
You could also use func_get_arg() or func_get_args(), but whatever you do would need to be before the global statement.
Works:
$t = function($x,$y) use (&$t){
...
}
Does not work:
$t = function($x,$y) use ($t){
...
}
Why must I pass the function itself as reference?
Maybe this will help:
$f = 42;
$f = function() use ($f)
{
var_dump($f);
};
$f();
That outputs 42.
The use() is hit before the function is defined and assigned to $f. So if you don't pass by reference, you are accessing the variable as it was before the function was created. In this case, 42. In your case, NULL.
By passing a reference, you'll get $f's value at the time the function is called, which will be the anonymous function as you are expecting (assuming you haven't reassigned $f).
Passing Reference variable means you are accessing same variable within that scope.
Reference variable points to the same variable that were previously created.
Example
<?php
$a = 10;
$b = &$a;
function change_b($pass)
{
$b = $pass++;
}
echo $b."<br />";
change_b(&$a);
echo $b;
?>
above code will output 10 and then 11.
Recursive function has to access the same resource over and over again and that is much more efficient than copying values.
I was wondering if it's possible to change and initialize variables in a function without passing arguments to the function. Here is what I want to achieve:
$foo = 'Lorem';
$array = array();
foobar($foo);
function foobar(){
if (strlen($foo)== 1)
$bar = 'Ipsum';
else
$array[] = 'error';
}
fubar();
function fubar(){
if (empty($fouten))
echo $bar;
}
$foo is a local (uninitialized) variable inside a function. It is different from the global variable $foo ($GLOBALS['foo']).
You have two ways:
$foo;
$bar;
$array = array();
function foobar(){
global $foo, $array, $bar;
if (strlen($foo)== 1)
$bar = 'Ipsum';
else
$array[] = 'error';
}
or by using the $GLOBAL array …
This is not really good practice though and will become a maintenance nightmare with all those side effects
Functions in php can be given arguments that have default values. The code you posted as written will give you notices for undefined variables. Instead, you could write:
function foobar($foo = null) {
if($foo) { // a value was passed in for $foo
}
else { // foo is null, no value provided
}
}
Using this function, neither of the below lines will produce a notice
foobar();
foobar('test');