Programming - - By Thomas Rutter

PHP 4.4 Minor Gotcha

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 D:htdocsaaaresourcesincludescontrols.inc.php, 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/$objecttype.inc.php");
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/$objecttype.inc.php");
$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.

Sponsors