I am following class based coding for project development.I have recently seen that some times we put "&" ahead of function name..
for an example..
rather than defining
function test()
it is defined like
function &test()
is there any special meaning of "&"?
As #philip mentions, it is to return a reference:
From the above link:
Note: Unlike parameter passing, here you have to use & in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for $myValue.
PHP stores every variable in a ZVAL container.
From the above link:
A zval container contains, besides the variable's type and value, two additional bits of information.The first is called "is_ref" and is a boolean value indicating whether or not the variable is part of a "reference set". With this bit, PHP's engine knows how to differentiate between normal variables and references. Since PHP allows user-land references, as created by the & operator, a zval container also has an internal reference counting mechanism to optimize memory usage. This second piece of additional information, called "refcount", contains how many variable names (also called symbols) point to this one zval container.
Observe the values of variable in the output:
Consider the following without & at the assignment of return value:
$b=0;
function &func ($name) {
global $b;
$b = 10;
return $b;
}
$a = func("myname");// no & at assignment
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/>";
The output for the above code:
$a= 11 $b= 10
a: (refcount=1, is_ref=0)=11
Although the function returns by reference, the reference is for the returned value's zval container. Now, when we are trying to assign the returned value, (say without a & at the assignment) only the "refcount" will increase. Where as the "is_ref" will not be altered. When the 'variable in which the returned value is stored', is tried to alter, a C.O.W (copy on write) takes place and a new zval container is created rendering the return by reference useless. Hence you will need to add the & at the assignment of the return value as well.
Consider the following with & at the assignment of return value:
$b=0;
function &func ($name) {
global $b;
$b = 10;
return $b;
}
$a =& func("myname");// & at assignment
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/>";
The output:
$a= 11 $b= 11
a: (refcount=2, is_ref=1)=11
pass by reference and return reference
This means that the function returns a reference to a variable.
You can read more about it here: http://php.net/manual/en/language.references.php
Related
I don't understand how it's possible to return an object from a function. Since objects are passed and returned by reference, If I created an object in a function, I'd expect such object to be destroyed after the function finishes executing. So such returned object reference should be referring to non-existing(destroyed) object. But my object created within a function is successfully returned. How come??
class O{
public $ppty = "ppty value";
}
function f1(){
$o1 = new O();
return $o1;
}
var_dump(f1());
**Result:**
object(O)[15]
public 'ppty' => string 'ppty value' (length=10)
A variable "holding" an object is actually holding a reference to the object. The object exists somewhere in memory, the variable referring to the object just holds the memory address (oversimplified). That's the reference. When returning that reference or passing it somewhere or assigning it to another variable, a copy of that reference is made (meaning the memory address value is copied; e.g. you return the value 0xDEADBEAF from your function; again, oversimplified). Those references are counted as a property of the object; only when the reference count reaches 0 (no variable is holding a reference to the object anymore), is the object garbage collected.
Consider the following example:
$var = 'test';
$ref = &$var;
unset($ref);
echo $var; // Echoes "test".
The unset is only removing the reference of $var to $ref, not destroying the original variable that $ref refers to. This is similar to your example of objects being references, and the garbage collection only removes the variable's reference to the object, but the object still exists in memory.
See http://php.net/manual/en/language.references.unset.php for more details.
When a function or scope of application is finished the local variables that are no longer accessible will be deleted. However, when you create object from a class the scenario is different. They won't be deleted automatically, there is a garbage collector in php that is constantly searching for objects that are no longer accessible and if it finds any it will delete them.
So when you return object reference from function it won't be deleted. If you won't store the reference in any variable GC will delete it later.
For more information about Garbage collector in php please read this link:
http://php.net/manual/en/features.gc.refcounting-basics.php
In PHP all values are stored in zvals. Those zvals contain the actual data and type information. checkout out the following example.
<?php
class O{
public $ppty = "ppty value";
}
$a = new 0; // $a is pointing to zval(class 0) with refcount 1
$b = $a; // $a and $b are pointing to zval(class 0) with refcount 2
$c = $b; // $a, $b and $c are pointing to zval(class 0) with refcount 3
unset($a) // new $b and $c are pointing to zval(class 0) with refcount 2
// until the refcount is greater then the 0 the destructor will not called
?>
now take a look at the following example
<?php
$a = new 0; // $a is pointing to zval(class 0) with refcount 1
unset($a) // here refcount is 0 and destruct will be called
?>
Now come to your example
<?php
function f1(){
$o1 = new O(); // refcount = 1
return $o1;
}
// now you are returning the object in function f1 and so,
// $o1 is gone after the function scope but the func f1 is now pointing the its reference.
var_dump(f1())
**Result:**
object(O)[15]
public 'ppty' => string 'ppty value' (length=10)
// once the process is finished then it will call the destruct.
This question already has answers here:
PHP param by ref => assign to ref = NULL
(1 answer)
PHP's assignment by reference is not working as expected
(7 answers)
Closed 8 years ago.
Here is the simplified version of code that might be revealing a PHP bug
class AClass
{
public static $prop = "Hi";
}
function assignRef (&$ref)
{
$ref = &AClass::$prop;
echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";
This prints out
inside assignRef: Hi
outside: Hello
Shouldn't $ref had been assigned by reference to $prop static variable of the AClass class and become "Hi" not just inside assignRef function but also outside of it?
The class in your example is irrelevant, simplified version that produces the same output:
function assignRef (&$ref)
{
$prop = 'Hi';
$ref = &$prop;
echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";
What is happening is that when assigning by reference inside the function ($ref = &$prop;) you are just changing what one variable is pointing to, not changing the value of what it was originally pointing to nor changing any other references to that original value.
You effectively have two variables called $ref in this example - one inside the function, and one outside the function. You are changing what the variable inside the function points to, leaving the other variable pointing to the original (unchanged) value.
Consider the following code:
$a = 'a';
$b = 'b';
$c = 'c';
$a = &$b;
$b = &$c;
echo "$a / $b / $c";
This results in output of b / c / c, rather than what you might expect c / c / c. This happens for the same reason - assignment by reference does not affect the value originally referenced nor change any other references, meaning any other variables pointing to the original value are unchanged.
If you want to change the value, rather than creating a new reference to another value, you must use normal assignment (=). Alternatively, you could change all references.
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.
(1) I want to know what is the difference between call by value and call by reference in php. PHP works on call by value or call by reference?
(2) And also i want to know that do you mean by $$ sign in php
For example:-
$a = 'name';
$$a = "Paul";
echo $name;
output is Paul
As above example what do u mean by $$ on PHP.
$$a = b; in PHP means "take the value of $a, and set the variable whose name is that value to equal b".
In other words:
$foo = "bar";
$$foo = "baz";
echo $bar; // outputs 'baz'
But yeah, take a look at the PHP symbol reference.
As for call by value/reference - the primary difference between the two is whether or not you're able to modify the original items that were used to call the function. See:
function increment_value($y) {
$y++;
echo $y;
}
function increment_reference(&$y) {
$y++;
echo $y;
}
$x = 1;
increment_value($x); // prints '2'
echo $x; // prints '1'
increment_reference($x); // prints '2'
echo $x; // prints '2'
Notice how the value of $x isn't changed by increment_value(), but is changed by increment_reference().
As demonstrated here, whether call-by-value or call-by-reference is used depends on the definition of the function being called; the default when declaring your own functions is call-by-value (but you can specify call-by-reference via the & sigil).
Let's define a function:
function f($a) {
$a++;
echo "inside function: " . $a;
}
Now let's try calling it by value(normally we do this):
$x = 1;
f($x);
echo "outside function: " . $x;
//inside function: 2
//outside function: 1
Now let's re-define the function to pass variable by reference:
function f(&$a) {
$a++;
echo "inside function: " . $a;
}
and calling it again.
$x = 1;
f($x);
echo "outside function: " . $x;
//inside function: 2
//outside function: 2
You can pass a variable by reference to a function so the function can modify the variable.
More info here.
Call by value: Passing the variable value directly and it will not affect any global variable.
Call by reference: Passing the address of a variable and it will affect the variable.
It means $($a), so its the same as $name (Since $a = 'name'). More explanation here What does $$ (dollar dollar or double dollar) mean in PHP?
Call by value means passing the value directly to a function. The called function uses the value in a local variable; any changes to it do not affect the source variable.
Call by reference means passing the address of a variable where the actual value is stored. The called function uses the value stored in the passed address; any changes to it do affect the source variable.
Recently i was studying the "Passing by Reference", I come to know following ways
What is the main difference between the following methods.
1.
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
2.
function foo($var)
{
$var++;
}
$a=5;
foo(&$a);
3.
function foo(&$var)
{
$var++;
}
function &bar()
{
$a = 5;
return $a;
}
foo(bar());
even though all of them produce same results, and which is the best way to work with.
Thanks.
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
This accepts a parameter that is always passed by reference (the & is in foo(&$var)). When $a is passed, it's always as a reference, so incrementing the variable inside the function will cause the parameter to be modified.
function foo($var)
{
$var++;
}
$a=5;
foo(&$a);
Do not use this. This is call-time pass-by-reference (you're passing &$a, a reference to $a, into the function), and is deprecated as of PHP 5.3.0. It's bad practice because the function doesn't expect a reference.
function foo(&$var)
{
$var++;
}
function &bar()
{
$a = 5;
return $a;
}
foo(bar());
This returns a reference (the & is in &bar()) to a variable $a declared in the function bar(). It then takes a reference to the return value of bar() and increments it. I'm not sure at a glance why this would be useful, though, especially for primitive/scalar types.
The second method is deprecated and should never be used.
Typically the function should just return the value.
function foo($a)
{
$a = 5;
}
$a = foo($a);
That's basically what the third method is doing. Not sure why you included an embedded pass by reference.
Pass by reference (for scalars and arrays) should generally be avoided because it's less clear than returning the value. However, it can be useful in cases where you need to modify multiple values within one function call.
Note that in PHP5, there's not even a need to explicitly pass an object by reference if you simply want to modify the original object, as the handle to the object will point to the same object as was passed to the function.
The last example is not equivalent to the first two. If you print the value of $a after calling foo, you will see that it is not defined. The third is basically an obfuscated no-op.