Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 5.3 and assigning the return value of new by reference

Tags:

php

Assigning the return value of new by reference has been deprecated in PHP 5.3. As such,

$obj =& new Foo();

now throws an E_DEPRECATED error.

When upgrading a large application with a lot of legacy code to 5.3, this leads to a lot of unwanted notices.

As a potential fix to this problem, I am considering using a regular expression to find and replace all instances of =& new with = new. For example, the following will find all PHP files, and wipe out all instances of =& new:

find ./ -name '*.php' | xargs perl -p -i -e 's/=(\s*)&(\s*)?new\b/= new/g'

Looking for answers to the following questions:

  1. Will it work just fine? What potential issues might I run into?
  2. If not, examples of code where replacing =& new with = new will change the behavior in PHP 5.3.
  3. Any examples of popular libraries with this would be known to cause a problem.
  4. What other ideas do you recommend to deal with fixing massive amounts of =& new?

I suspect this will work just fine, but looking for edge cases where I might run into trouble. Yes, I know I could just change the error reporting settings. But I don't want to hide the notices, I want to fix them.

like image 209
mfonda Avatar asked Jan 12 '11 20:01

mfonda


2 Answers

Your feeling is right. It will generally work fine, but there are edge cases where it doesn't.

Using =& has these differences with =:

  • =& will try to make the right side yield a reference; = won't -- even if the right side is able to yield a reference, like a function which returns by reference.
  • =& will break the old reference set and put the left and the right side both in a new one, while = will change the value of all the elements in the same reference set as the left side to the value of the right side.

The first difference and half of the second is irrelevant in this case. After the assignment, there will be only one variable with the value of the new object*, and single-element reference sets make no sense. However, the fact that =& breaks the previous reference set is significant:

<?php

$g = 4;
$v =& $g;
$v = new stdclass();
var_dump($g); // object(stdClass)#1 (0) { }

$g = 4;
$v =& $g;
$v =& new stdclass();
var_dump($g); // int(4)

* Unless maybe the constructor leaks a reference, but even if it leaks, $this inside the constructor may be a different variable, even if it points to the same object. So I doubt one could observe behavior difference due to this.

like image 175
Artefacto Avatar answered Oct 23 '22 18:10

Artefacto


Yes, you should be able to just replace =& new with = new. Objects are passed by reference by default in PHP 5.3, so no behavior will change.

+1 for fixing notices instead of hiding them.

like image 29
Jonah Avatar answered Oct 23 '22 16:10

Jonah