What's the point of writing : $foo = & new someClass();? - php

I am getting a deprecated warning because of a library I am using. The statement is the following :
$this->_ole =& new OLERead();
The thing is I don't see why one would want to use & new in an instantiation.
If I am not mistaken, the & operator tells PHP to copy the reference to the instance, and not the instance itself. But in that case, isn't it pointless to ask for a copy of a reference that isn't stored ?
But since I don't exactly know how new exactly works, maybe this was supposed to save some obscure garbage collection, or something like that.
What do you think about that ?

From the documentation:
As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions.
The library you use was probably developed for PHP 4.
Helpful information about why this was used can also be found in the migration guide:
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).

That's an idiom for PHP4 compatibility. Objects were passed as copies per default there, and this is a workaround to always have references to an instance.

In PHP4, new returned a value and not a reference.
This is not the case in PHP5.

If you write $this->_old =& new OLERead(); a changement of _ole in any object will updates all references to the new object.
This is not the case without & .
EDIT: And yes, in previous versions of PHP, object were passed by copy. At the end, this is quite hard to have a consistent behaviour accross versions.

Related

Has PHP always made copies when using object assignment?

For example, I have the following class.
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // a copy of the same identifier (NB)
According to the current PHP docs a copy of the identifier is made, has this always been the case? If not, when did it change?
This wasn't always the case. In PHP4 an object was copied when assigned to a new variable. When PHP5 was introduced this changed to pass a reference of the object being assigned.
(From the manual)
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).

PHP ignoring returned reference from function considered harmful?

Derick Rethans has an old article that says:
Please do note that it is harmful not to accept a reference from a
function that returns a reference. In some cases, PHP will get
confused and cause memory corruptions which are very hard to find and
debug. It is also not a good idea to return a static value as
reference, as the PHP engine has problems with that too. In PHP 4.3,
both cases can lead to very hard to reproduce bugs and crashes of PHP
and the web server. In PHP 5, this works all a little bit better. Here
you can expect a warning and it will behave “properly”.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
By that, I mean this:
function &GetRef(&$array){
$item =& $array[0];
return $item;
}
$array = array(0, 1, 2);
$item =& GetRef($array); /* Normal usage of the function using assign by reference
also known as "accepting" the reference. */
$item = GetRef($array); /* Notice that here we didn't assign by reference.
Are we allowed to ignore the returned reference
and simply do normal assignment? */
The PHP Manual states:
Unlike parameter passing, here [return by reference] 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.
It doesn't explicitly say that we must accept the returned reference.
Does it mean that we are free to ignore returned references?
As discussed in the comments, you should generally ignore at least that section in the linked article, if not the entire thing.
The article talks about references in the context of PHP 4.3, released in December, 2002 and EOL'd at the end of 2007. PHP 4 should never be used today. As a general rule, when it comes to learning about working with PHP, you should not trust any article that targets PHP versions older than 5.2 (as of mid-2013).
PHP 5.0 features Zend Engine 2, a new virtual machine on which PHP runs. This is where references are implemented. 5.1 introduces some backwards-incompatible changes with regard to manipulation of return values. 5.3 introduces real garbage collection and deprecates both call-time pass-by-reference and assigning new by reference. These important changes are not addressed by that prehistoric article.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
Yes. Modern PHP versions have no problem with discarding the return value of any function, reference or not. If you encounter behavior that seems to contradict this expectation, create a reduced test case and file a bug with the PHP maintainers.
Also, think twice before using references in your code. Passing around references will not save time, will not save memory and will not increase performance except in rare cases. Use them sparingly to keep complexity under control.

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.

questions about php references

when I was looking for some MVC framework, I got the website:
http://www.phppatterns.com/docs/design/archive/model_view_controller_pattern
however, like the code listed there makes me confused about references.
For example:
$dao=& new DataAccess ('localhost','user','pass','dbname');
$productModel=& new ProductModel($dao);
each instance it makes, it adds '&' before the new operator, what does it exactly mean? the reference to the instance? Actually, I removed all the '&' before all these kind of instances and the code still works perfectly.
Another, codes like :
function ProductView (&$model) {
$this->model=& $model;
}
I really think it could be revised like:
function ProductView (&$model) {
$this->model=$model;
}
Am I right? what's the differences between these two? Actually, like the MVC code example listed above? if you revise the code like I did, the code still works.
Then, I got this post somewhere else:
http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html
does it make sense? any suggestions about this would be helpful.
Prior to PHP version 5 objects were passed by value and you had to explicitly specify the ampersand to get the object by reference.*
In PHP 5+, all objects are passed by reference and thus using ampersand is redundant.
Furthermore, as of PHP 5.3.0, code like the above will generate a STRICT error of "Assigning the return value of new by reference is deprecated".
If you're curious about the historical use (PHP 4 or before) of "$o =& new Object()" code see php-by-reference (in particular, the accepted answer there provides a good explanation).
To summarise:
in PHP 5 or above, it makes no difference. The code will work as expected with no memory or other differences.
In PHP 5.3 you might get some STRICT notices complaining about this usage (assuming you have STRICT notices turned on).
In PHP 4.x (or earlier) this method was used to prevent unnecessary duplication of objects.
(*) Passing references around is a good thing - no need to create copies of objects when you only need the one instance.

PHP new operator returning reference

I'm working with some old PHP code that has a lot of the following:
$someVar =& new SomeClass();
Did the new operator ever return a value, um, not by reference? (That feels strange to type. I feel like I'm losing my mind.)
It was one of those sort of optimization techniques taught in a lot of older books on OOP in PHP 4.
Basically, the initial object created in memory is one the application can't access unless you return the instance by reference. Otherwise you get a copy of the object - the only catch is that the original exists without a symbol. Kinda dumb.
But ya, object creating and passing and references in PHP 4 is a monumental mess.
Thats PHP4 code.
From the documentation: (now removed)
"new" does not return a reference by
default, instead it returns a copy.
[1]: http://no.php.net/manual/en/language.oop.newref.php
See also my answer here which includes a simple code sample to illustrate the issue.

Categories