By Thomas Rutter

PHP 4.4 Minor Gotcha

By Thomas Rutter
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

In the days after the release of PHP 4.4, it was interesting to watch the discussions surrounding a possible backwards compatibility issue which had been introduced with the release. Commentors seemed to be divided on whether this did, or did not, actually constitute a break in backwards compatibility.

The ‘backwards-compatibility break’ is in fact a new notice generated by the PHP error-handling code, warning developers when trying to return a temporary variable by reference. The notice seems to have been added in response to a bug in PHP 4.3 in reference handling.

Today, when I upgraded my own development server at home to PHP 4.4, I was confronted by the problem. An application I’ve been working on runs in its own ‘debug’ mode, which makes notices really visible by echoing the notice to output.

The culprit:

Notice in, line 14: Only variable references should be returned by reference

The line in question falls in the following method:

function &getnodecontrol($objecttype)
require_once(RESOURCE_DIR . "nodecontrols/$");
return new $objecttype($this->db);

The problem here is that “new $objecttype($this->db)” is not a variable – it is the result of a “new” statement – effectively a ‘temporary’ variable – which PHP can’t create a reference to. The only thing that can be returned, when the variable returns by reference, is a variable which has been initiated.

As the PHP manual puts it under returning references:

Note: If you try to return a reference from a function with the syntax: return ($found_var); this will not work as you now try to return the result of an expression, and not a variable, by reference. You can only return variables by reference from a function – nothing else.

The problem is solved, and the notice is surpressed, with the following code:

function &getnodecontrol($objecttype)
require_once(RESOURCE_DIR . "nodecontrols/$");
$control = new $objecttype($this->db);
return $control;

Here, the result of “new $objecttype($this->db)” is stored into a variable, and a reference to that variable is returned.

This article from eZ Systems describes the change in a bit more detail.

The change in behaviour was criticised by some whose applications were affected by this change. One example is this message about a problem with Horde, the web email client.

In response, others have pointed out that notices should not be enabled in a production environment anyway, and therefore the change shouldn’t have caused any problem.

The Zend weekly summary (#245) provided an amusingly concise summary of the Horde issue.

Interestingly that discussion links to a newer bug in PHP 4.4 which involves passing by reference. It hints that a future update to PHP 4.4 might be needed in order to fix it, and that update might introduce a new warning and/or break backward compatibility.

Login or Create Account to Comment
Login Create Account
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?