Would you consider this a bug, or at least unexpected behaviour?

php 4.3.10 windows, and 4.3.9 nixxy both give the same output

	function &gooGoo()
	{
		static $y = 'Y Static Initial val';
		echo "gooGoo Y: $y<br>";
		return $y;
	}

$foo = &gooGoo();	$foo = 'Change one';	// yes, expect change
$foo = gooGoo();	$foo = 'Second change';	// don't expect change - but there IS
$baz = gooGoo();	$baz = 'Third go';		// don't expect change - and there isn't
gooGoo();

    Its expected since you are returning by reference...

    It may be a little clearer like this, i think

    <?php
    function &gooGoo()
        {
            static $y = 'Y Static Initial val';
            echo "gooGoo Y: $y<br>";
            return $y;
        }
    
    $foo = &gooGoo(); //return reference of $y to $foo
    $foo = 'Change one';    //foo points to the same address as $y,
                            //so the value "changes" for both
    
    $foo = gooGoo(); //reference still exists, technically you dont even
                     //need the assignment.  gooGoo() would do the same
    $foo = 'Second change'; //foo still points to address of $y
    
    $baz = gooGoo(); //$y = 'Second change' return this value to $baz
    $baz = 'Third go';  //$baz does not point to $y or $foo so they wont change
                        //if you did $baz =& gooGoo(); it would change the reference
    
    gooGoo();  //no changes in reference.  $y and $foo still point to same place
    
    ?>
    

      Here's my interpretation:

      1. On the first call to gooGoo(), $foo becomes an alias for $y in gooGoo().
      2. When $foo is set to 'Change one', $y in gooGoo() is also set to 'Change one'.
      3. In the 2nd call to gooGoo(), 'Change one' is printed since that's the value of $y.
        $foo = gooGoo() effectively assigns $y to $foo - but $foo already is $y, so there's no net effect.
      4. When $foo is set to 'Second change', $y in gooGoo() is also set to 'Second change'.
      5. In the 3rd call to gooGoo(), 'Second change' is printed since that's the value of $y.
        $baz = gooGoo() assigns the value of $y to $baz.
      6. When $baz is set to 'Third go', $y remains set to 'Second change' since $baz is not an alias for $y.
      7. In the 4th call to gooGoo(), 'Second change' is print since that's the value of $y.

      Basically the ampersand must be used in both the function definition and function call for return by reference to work as expected.

        Originally posted by laserlight
        Here's my interpretation:

        1. In the 2nd call to gooGoo(), 'Change one' is printed since that's the value of $y.
          $foo = gooGoo() effectively assigns $y to $foo - but $foo already is $y, so there's no net effect.

        Basically the ampersand must be used in both the function definition and function call for return by reference to work as expected. [/B]

        My interpretation when I found this was the same as point 3. Really foo should be set to a COPY of $y, not a reference on its 2nd call as the ampersand isn't used, so the internal $y shouldn't change on $foo = 'second change', and this is illustrated when $baz is assigned.

        I'm going to write another experiment that allows the changing of the static y with via a different path and see if it splits the reference count and what I would consider the same.

          after you return by reference one time from a function to a variable, the reference remains in place.

          i.e.

          function &x()
          {
            static $x = 0;
            ++$x;
            echo "func \$x = $x<br />\n";
            return $x;
          }
          
          $xx =& x(); //$xx = 1, $x = 1 $xx points to the same addr as $x
          
          x();  //$xx = 2 $x = 2
          x();  //$xx = 3 $x = 3
          
          ++$xx; //$xx = 4; $x = 4
          
          x();
          
          echo $xx;  //outputs 5
          

            Hi Drew. I know about the reference staying in place, but what was fooling me in my example was the second assignment to $foo without the ampersand. It looks like it shouldn't work, you're not assigning by reference the 2nd time, so how does a change of $foo change $y - this now explains it and puts the beast to sleep in my head, it was nothing to do with reference counting or anything that I tried explaining it with, essentially a 'trick of the light'.

            <?php
            	function &gooGoo($returnString = 0)
            	{
            		static $yStatic = 'Y Static Initial val';
            
            	echo "gooGoo Y: $yStatic <br>";
            
            	if ($returnString)
            	{
            		echo ' you want string, you get string<br />';
            
            		$yStatic = 'change by string condition';
            
            		return 'Hi, I am returned string';
            	}
            	else
            	return $yStatic;
            }
            
            $proxy = &gooGoo();		// get a control reference to $yStatic
            
            $foo = &gooGoo();		// $foo a definite reference to $yStatic
            $foo = 'Change one';	// so $yStatic = 'Change one';
            
            $foo = gooGoo(1);
            /*	Above I now know $foo equals 'Hi, I am a returned string'
            	and I assume $yStatic now to be 'change by string condition'
            	but check it out and it's NOT.  
            
            	$foo = gooGoo(1) the 2nd time essentially behaves as
            	$yStatic = 'Hi, I am a returned string' because 
            	$foo IS $yStatic - the eye is just fooled by $foo = gooGoo(1);
            */
            
            echo "\$foo = $foo<br />";
            echo '\$proxy = ', $proxy, '<br />';
            
            $foo = 'Second change';		// surely no change - but there IS [though now understood]
            
            $baz = gooGoo();
            $baz = 'Third go';		// don't expect change - and there isn't, and never was
            
            gooGoo();	
            ?>
              Write a Reply...