🤯 50% Off! 700+ courses, assessments, and books

PHP 4.4 Minor Gotcha

    Thomas Rutter

    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.