what does "&" mean in front of classes in php? - php

I've just inherited this code in PHP which seems to do some kind of web service call to googles api. I'm not quite an expert on PHP and there is a few syntax questions I have specifically relating to the following line
$soapClients = &APIlityClients::getClients();
I understand the double "::" as indicating that APIlityClients is a static class but I'm not sure what the "&" in front of APIlityClients means.

When you use an ampersand in front of a variable in PHP, you're creating a reference to that variable.
$foo = 'bar';
$baz = &$foo;
echo $foo //bar
echo $baz //bar
$foo = 'foobazbar';
echo $foo //foobazbar
echo $baz //foobazbar
Prior to PHP5, when you created an object from a class in PHP, that object would be passed into other variables by value. The object was NOT a reference, as is standard in most other object oriented (Java, C#, etc.) languages.
However, by instantiating a class with an ampersand in front of it, you could create a reference to the returned object, and it would behave like an object in other languages. This was a common technique prior to PHP5 to achieve OOP like effects and/or improve performance.

It is PHP's version of getting a reference to something rather than copying its value. So in this case the & would retrieve a reference to the return value of APIlityClients::getClients() rather than a copy of the return value itself.

It means "address of" - and it's referring to the value returned from the getClients() call, not the APllityClients class itself.
Basicly it's saying to assign $soapClients to a reference to whatever is returned from getClients() rather than making a copy of the returned value.

& indicates a pass by reference rather than by value. It doesn't apply much in PHP5 since classes are passed by reference by default in that version, but weren't in previous versions.

the & means it's a reference. References are used to allow multiple variables point to the same object.
this page explains it better than I can though
Also see http://us3.php.net/manual/en/language.references.php for more information on references in php in general

Related

Cannot access variable property with getter method

In PHP, I cannot assign a value to a variable unless I access its property without using a getter method, is it by design or I missed something?
Simply put, when I do $article->content->value[$some_value] = 'hello' it works, but $article->get_value()[$some_value] = 'hello' sets nothing, the array remains empty.
What the get_value does is just return $this->content->value, and when used as a getter, it does what it supposed to do as expected.
I feel like I missed some basic here, if someone could share me why setting value doesn't work, it'll be great.
Unlike objects, arrays aren't returned by reference in PHP, so when you call the getter method, you're getting back a copy.
If you want to modify the object property itself then you can change the method definition to return a reference by prepending the method name with an ampersand, e.g.
public function &getArray()
{
return $this->array;
}
See https://3v4l.org/1YK9H for a demo
I should stress that this is absolutely not a common pattern in PHP, other than perhaps a long way back into the PHP 4 days when OOP was a lot less ubiquitous. I certainly wouldn't expect a class I was using to return arrays by reference, and neither would I recommend anyone else doing it. Note that it's not possible to ask the class for a reference, in order to prevent unwanted modifications to private properties - the class has to define the behaviour.
The PHP documentation has more information about returning by reference here: http://php.net/manual/en/language.references.return.php

What's the point of an ampersand '&' before the 'new' keyword?

Why would you do this?
$a = &new <someclass>();
For example, the documentation for SimpleTest's SimpleBrowser uses this syntax (http://www.simpletest.org/en/browser_documentation.html).
$browser = &new SimpleBrowser();
Is there any use to this? Is this a relic of PHP 4?
Edit:
I understand that the ampersand returns by reference, but what is the point of returning a NEW instance of an object by reference?
In PHP5, objects are passed using opaque object handles. You can still make a reference to a variable holding such a handle and give it another value; this is what the &new construct does in PHP5. It doesn't seem to be particularly useful though – unless you clone it explicitly, there's only ever one copy of a particular object instance, and you can make references to handles to it anytime after instantiation if you want to. So my guess would be the code you found is a holdover from when &new was a necessary pattern.
Since PHP5 new returns references automatically. Using =& is thus meaningless in this context (and if I'm not mistaken giving a E_STRICT message).
Pre-PHP5 the use of =& was to get a reference to the object. If you initialized the object into a variable and then assigned that to a new variable both of the variables operated on the same object, exactly like it is today in PHP5.

Help me understand PHP variable references and scope

References:
If I pass a variable to a function (e.g. $var), is that supposed to be a copy of a reference to the actual variable (such that setting it null doesn't affect other copies)?
Or is it receiving a reference to what is a new copy of the actual variable (such that setting it to null destroys its copy only)?
If the latter, does this copy objects and arrays in memory? That seems like a good way to waste memory and CPU time, if so.
I think can understand passing by reference (e.g. &$var) correctly by knowing how this works, first.
Scope:
What's the deal with local scope? Am I right in observing that I can declare an array in one function and then use that array in other functions called within that function WITHOUT passing it to them as a parameter?
Similarly, does declaring in array in a function called within a function allow it to be available in the caller?
If not, does scoping work by a call stack or whatever like every bloody thing I've come to understand about programming tells me it should?
PHP is so much fun. :(
If I pass a variable to a function (e.g. $var), is that supposed to be a copy of a reference to the actual variable (such that setting it null doesn't affect other copies)?
Depends on the function. And also how you call it. Look at this example:
http://www.ideone.com/LueFc
Or is it receiving a reference to what is a new copy of the actual variable (such that setting it to null destroys its copy only)?
Again depends on the function
If the latter, does this copy objects and arrays in memory? That seems like a good way to waste memory and CPU time, if so.
Its going to save memory to use a reference, certainly. In php>4 it always uses reference for objects unless you specify otherwise.
What's the deal with local scope? Am I right in observing that I can declare an array in one function and then use that array in other functions called within that function WITHOUT passing it to them as a parameter?
No you can't.
Similarly, does declaring in array in a function called within a function allow it to be available in the caller?
No, it doesn't.
If not, does scoping work by a call stack or whatever like every bloody thing I've come to understand about programming tells me it should?
If you want to use a variable from outside the function, before using it, you'd write global $outsidevar
Concerning your first set of questions:
foo($a);
function foo($b) { echo $b; }
In this case, $a will not be copied to a new variable $b, only because it is passed by value.
This is because PHP uses the copy-on-write concept. PHP will not copy the contents of a variable, unless they are changed. Instead PHP will increment the refcount property of the existing "zval" of $a.
Well, the whole thing is not that trivial, but to answer your question: No, it does not copy the variable, unless you write to it in the function and no, you won't save CPU and Memory by using a reference. In most cases the reference won't change performance at all, but in the worst case it will actually degrade it (because if a not is_ref variant of the variable already exists and a reference is created the value of the variable must be copied to get a zval with is_ref and one without). Optimizing code by using references is no good.
if argument to a function is defined as so "function my_function($variable) {}" then you are getting a copy of the variable and any alterations made to the variable inside your function will not be available to the function caller. you can pass a variable by reference by prepending an ampersand to the argument when defining your function and thus any alterations made to the variable will persist to the function caller, ie "function my_function(&$variable) {}"
function myfunction($var) {
$var = 'World';
}
$var = 'Hello';
myfunction($var);
echo $var; // 'Hello';
Passing a variable by reference
function myfunction(&$var) {
$var = 'World';
}
$var = 'Hello';
myfunction($var);
echo $var; // 'World'

Symbol in PHP I've never come across before

I probably should have, but I've never seen this before. Ran into it when looking over the documenation of a Smarty Plugin.
$smarty =& new Smarty;
The =& sign in particular. If you enter it in Google, it gets ignored, just like any other search engine. What is this used for?
Same goes for this function signature:
function connect(&$smarty, $reset = false)
Why the & symbol?
Actually, this code is written to be compatible with PHP 4. The ampersand is useless in PHP 5 (as Tim said - since PHP 5, all objects are passed by reference).
With PHP 4, all variables were passed by value.
If you wanted to pass it by reference, you had to declare a reference assignment :
$ref_on_my_object =& new MyObject();
This code is still accepted with PHP 5 default configuration, but it's better to write :
$ref_on_my_object = new MyObject(); // Reference assignment is implicit
For your second problem, the issue is "almost" the same...
Because PHP lets you declare function arguments (resp. types), and you can't do it for return values.
An accepted, but "not so good" practice is to avoid reference declaration within the function's declaration :
function foo($my_arg) {
// Some processing
}
and to call with a reference...
$my_var;
$result = foo( &$my_var );
// $my_var may have changed because you sent the reference to the function
The ideal declaration would be more like :
function foo( & $my_input_arg ) {
// Some processing
}
then, the call looses the ampersand :
$my_var;
$result = foo( $my_var );
// $my_var may have changed because you sent the reference to the function
It is used for passing values by reference rather than by value which is default in php.
& passes an argument by reference. In this fashion, connect() can manipulate the $smarty object so that the calling function can retrieve the modified object.
Similarly, =& sets a variable by reference.
As Tim said its a reference to a variable. But if you're using a recent version of PHP then all class object are passed by reference anyway. You would still need this if you were passing about arrays, or other builtin types though.
The first example is returning reference, the second is passing reference.
You can read all about it in the PHP manual
& is PHP's reference operator. It's used to return a reference to the object. In this case "new Smarty".
The ampersand will assign a reference to the variable, rather than the value of the object.
One of the primary uses of the ampersand operator is to pass by memory address. This is usually something you do when you want to have a variable changed, but not be returned.
function test_array(&$arr)
{
$varr[] = "test2";
}
$var = array('test');
test_array($var);
print_r($var);
this should output
array( test , test2 );
The purpose of this is usually when you need to pass the actual copy[memory address] you are working with into another function / object. Typically it was used in the past to alleviate a lack of memory and speed up performance, it's a feature from C / C++ and a few other low level languages.

Php By Reference

Can someone please explain what the "&" does in the following:
class TEST {
}
$abc =& new TEST();
I know it is by reference. But can someone illustrate why and when I would need such a thing? Or point me to a url where this is explained well. I am unable to grasp the concept.
Thank you very much.
As I understand it, you're not asking about PHP references in general, but about the $foo =& new Bar(); construction idiom.
This is only seen in PHP4 as the usual $foo = new Bar() stores a copy of the object. This generally goes unnoticed unless the class stored a reference to $this in the constructor. When calling a method on the returned object later on, there would be two distinct copies of the object in existence when the intention was probably to have just one.
Consider this code where the constructor stores a reference to $this in a global var
class Bar {
function Bar(){
$GLOBALS['copy']=&$this;
$this->str="hello";
}
}
//store copy of constructed object
$x=new Bar;
$x->str="goodbye";
echo $copy->str."\n"; //hello
echo $x->str."\n"; //goodbye
//store reference to constructed object
$x=&new Bar;
$x->str="au revoir";
echo $copy->str."\n"; //au revoir
echo $x->str."\n"; //au revoir
In the first example, $x and $copy refer to different instances of Foo, but in the second they are the same.
Firstly, you don't really need to use it if you are using PHP 5, in PHP 5 all objects are passed by reference by default.
Secondly, when you assign an object to a variable name, either by creation, passing in a parameter, or setting a variable value, you are either doing so by reference or value.
Passing by reference means you pass the actual memory reference for the object, so say you passed an object as a parameter to a function, any changes that function makes to that variable will be reflected in the parent method as well, you are actually changing the state of that object in memory.
The alternative, to pass by value means you pass a copy of that object, not the memory reference, so any changes you make, will not be reflected in the original.
The PHP Manual does a pretty decent job of explaining references.
I should note, that they are NOT the same thing as a pointer or a reference in many other languages, although there are similarities. And as for objects being "passed by reference" by default - that's not exactly true either.
I would recommend reading the manual section first (and probably then re-reading a couple of times until you get it), and then come back here if you still have more questions.
A simpler way to look at it may be like this:
$a = 'foo';
$b = 'bar';
$a =& $b;
$b = 'foobar';
echo $a . ' ' . $b;
will output
foobar foobar
It might be helpful to think of it like this: In PHP, all variables are really some sort of pointer: The entries in the symbol table - the thing which maps variable names to values - contain a zval * in the C implementation of the Zend Engine.
During assignment - this includes setting function arguments - magic will happen:
If you do $a = $b, a copy of the value pointed to by the symbol table entry of $b will be created and a pointer to this new value will be placed in the symbol table entry for $a. Now, $a and $b will point to different values. PHP uses this as its default calling convention.
If you do $a =& $b, the symbol table entry for $a will be set to the pointer contained in the symbol table entry for $b. This means $a and $b now point to the same value - they are aliases of each other with equal rights until they are rebound by the programmer. Also note that $a is not really a reference to $b - they are both pointers to the same object.
That's why calling them 'aliases' might be a good idea to emphasize the differences to C++' reference implementation:
In C++, a variable containing a value and a reference created from this variable are not equal - that's the reason why there are things like dangling references.
To be clear: There is no thing like a reference type in PHP, as all variables are already internally implemented as pointers and therefore every one of them can act as a reference.
PHP5 objects are still consistent with this description - they are not passed by reference, but a pointer to the object (the manual calls it an 'object identifier' - it might not be implemented as an actual C pointer - I did not check this) is passed by value (meaning copied on assignment as described above).
Check the manual for details on the relation between PHP5 objects and references.

Categories