11

I wrote the following code:

<?php
    $a1 = "WILLIAM";
    $a2 = "henry";
    $a3 = "gatES";

    echo $a1." ".$a2." ".$a3. "<br />";

    fix_names($a1, $a2, $a3);

    echo $a1." ".$a2." ".$a3;

    function fix_names(&$n1, &$n2, &$n3)
    {
        $a1 = ucfirst(strtolower(&$n1));
        $a2 = ucfirst(strtolower(&$n2));
        $a3 = ucfirst(strtolower(&$n3));

    }

    ?>

I received this notice: Deprecated: Call-time pass-by-reference has been deprecated

I need an explanation why did I receive this notice? And why in PHP Version 5.3.13, this has been deprecated?

John Parker
  • 54,048
  • 11
  • 129
  • 129
Muhammad Maqsoodur Rehman
  • 33,681
  • 34
  • 84
  • 124
  • http://stackoverflow.com/questions/4665782/call-time-pass-by-reference-has-been-deprecated?answertab=votes#tab-top – Telvin Nguyen Aug 04 '13 at 19:45
  • 3
    Was there any particular reason why you were using call-time pass-by-reference here anyway? – Mark Baker Aug 04 '13 at 19:45
  • As for why (only a guess): Call-time pass-by-reference might lead to unexpected behavior if the function does not expect references. – Felix Kling Aug 04 '13 at 19:46
  • 8
    Found the [official reason](http://www.php.net/manual/en/ini.core.php#ini.allow-call-time-pass-reference): *"Passing arguments by reference at function call time was deprecated for code-cleanliness reasons. A function can modify its arguments in an undocumented way if it didn't declare that the argument shall be passed by reference. To prevent side-effects it's better to specify which arguments are passed by reference in the function declaration only."* – Felix Kling Aug 04 '13 at 19:49
  • Just like to see what happens! – Muhammad Maqsoodur Rehman Aug 04 '13 at 19:55

3 Answers3

11

This is all documented on the PHP Passing by Reference manual page. Specifically (added emphasis mine):

Note: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.

As such, it was deprecated (and will throw a warning) in PHP 5.3.x and will fail in PHP 5.4.

That said, it's a trivial fix. Simply update your fix_names function as follows:

function fix_names(&$n1, &$n2, &$n3)
{
    $a1 = ucfirst(strtolower($n1));
    $a2 = ucfirst(strtolower($n2));
    $a3 = ucfirst(strtolower($n3));

}

Incidentally, the 5.3.x series is getting quite long in the tooth, so it would be wise to update to a more recent build (after carrying out the necessary testing) if at all possible.

John Parker
  • 54,048
  • 11
  • 129
  • 129
  • 2
    While this explains the status quo, it doesn't answer the title question as to **why** call-site references have been deprecated. – TheOperator Jun 29 '16 at 07:08
  • Obviously because it's unnecessarily slower to parse and interpret. – Heitor Aug 30 '17 at 09:26
  • 1
    It was worse that that: When you have written the function, there was no clear contract, whether it is safe, or desired to change the parameter values. Similarly looking calls would do rather different things to the passed variables and such subtle errors were VERY hard to find. Lucky us, it's over. – Thinkeye Dec 05 '18 at 16:15
0

Remove the & symbols from your like: &$n1, &$n2, ...

ale
  • 11,636
  • 27
  • 92
  • 149
-1

use this....

fix_names(&$a1, &$a2, &$a3);

TK Singh
  • 29
  • 1