Valery's Mlog

Mindlog of a Freak
November 5th, 2005 by Valery Dachev

PHP References

PHP 5.0.5 came out exactly two months ago. The entering of this version into Debian (testing and unstable) was forces, despite all the problems that were notices. This made the older versions unavailble on the servers. However all the chaos that took place was caused by the developers’ unawareness and the initial tollerance of PHP to their errors. In order to have backwards compatibility, there’re options that keep this tollerance. Some of the problems during the work of some different PHP software are because of developers’ misunderstanding for PHP references. They’re an analogue of pointers in other languages and Perl references. References are declared with an ampersand sign (&) before ht doller sign used for a variable. If the declaration of a function says that some of it’s arguments is a reference, it means that we work with the contents of the variable passed, not with it’s copy. There’re two serious advantages:

  • no copy of the variable contents is made during the function call. This is very important especially in cases when the variable holds a large amount of data (e.g. the contents of a file), because it saves the memory needed for the copy, as well as the overhead of the copying itself;
  • the change of the contents reflects in the context of the call, too, without the need to return it as a result of the function;

I will illustrate the most common errors that became a reason to write this post:

<?
    // NOTE: first parameter is a reference to the variable, not the variable itself
    function display( &$arr )
    {
       var_dump( $arr );
    }
    function &explode1( $delimiter, $str )
    {
       return explode( $delimiter, $str );
    }
    $str = ‘1|2|3’;
    $exploded = explode( ‘|’, $str );
    // ERROR: the result of a function can’t be referenced
    //! display( explode( ‘|’, $str ) );
    // WARNING: old syntax. references can now declared in function declarations only.
    //! display( &$exploded );
    // CORRECT: $exploded variable can be references
    display( $a = explode( ‘|’, $str ) );
    // CORRECT: the variable $tmp holds the result, so we can pass it
    display( $exploded );
    // CORRECT: the result of explode1() is declared to be a reference
    display( explode1( ‘|’, $str ) );
?>

The change in PHP 5.0.5 is that the first call causes and error message "Fatal error: Only variables can be passed by reference in…". In a matter of fact, this is a the correct behaviour because the result of a function cannot be accessed with a reference, although in the previous this used to work. In the last example however this works, because the explode1() function returns a reference which can be directly passed as an argument of display(). This is the most common mistake in lots of software, e.g. SquirrelMail, Drupal, phpBB, many PEAR libraries and so on… The possible solutions are to wait for newer releases of this software ot to keep the older PHP version. However it’s a real shame for a qualified programmer to show such a misunderstanding. Additionally I have a suspicion that the documentation of some built-in PHP functions doesn’t show that some of the arguments should be references.

The old syntax example, depending on the PHP settings, can lead to a warning "Call-time pass-by-reference has been deprecated – argument passed by value". This means that the behaviour will be different than the expected. This is usually caused by disabling or removing the "allow_call_time_pass_reference" option in php.ini.

Unfortunately this change in PHP 5.0.5 causes many incompatibilities with older or not confirming PHP software. I personally had the change to had kept the old packages (PHP 5.0.4) in /var/cache/apt/archives. I don’t what to do further…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: