简体   繁体   中英

PHP 5.3 and assigning the return value of new by reference

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.

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.

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.

There shouldn't be any problems. In the worst case this will slow down your application on PHP 4 slightly, but it definitely won't change functionality.

The only problem you could theoretically run into, is that somebody wrote =& new in a string. I know, this is highly improbable, but if you want to replace really only all occurences of '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW you should do so using the Tokenizer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM