4

I'm trying to return a value from a method as a reference in PHP5.3. I may be going at this the completely wrong way, but I am bringing an older project up to speed with some of the newer 5.3+ features.

Below is an example I whipped up to explain what is happening:

class Foo
{
    static $foobar = 5;

    function &bar()
    {
        return self::$foobar;
    }
}
// Doesn't work
//$test1 = &call_user_func_array(array("Foo","bar"),array());

// Doesn't work
//$test1 = &call_user_func_array("Foo::bar",array());

// Doesn't work
//$f = new Foo; $test1 = &call_user_func_array(array($f,"bar"),array());

// WORKS
//$test1 = &Foo::bar();

//Doesn't work
//$function = "Foo::bar";
//$test1 = &$function();

// WORKS
$f = new Foo; $test1 = &$f->bar();

$test2 = Foo::bar();

var_dump($test1);
var_dump($test2);

$test1 = 10;
echo "----------<br />";

var_dump($test1);
var_dump($test2);
var_dump(Foo::bar()); //returns 10 when working, 5 when not working

The very last Foo::bar() should return a 10, since $test1 should be a reference to Foo::$foobar when everything works.

I realize that this example also uses some funky legacy PHP calling Foo::bar and the method bar() not being specified as static, but still being able to be invoked via ::

Any help would be greatly appreciated as the only fix I have so far is to just setup a switch on the argument list, and call the method directly based upon how many arguments exist.

tamagokun
  • 83
  • 3
  • Shouldn't Foo::bar() return the reference instead of referencing the result? I think $test1 is now a reference to a copy of Foo::$foobar ? – PtPazuzu Dec 15 '11 at 15:53
  • @PtPazuzu since you can't return a reference, something like `$result = &self::$foobar; return $result;` doesn't seem to change anything. using the code above with a working $test1 assignment, even doing `var_dump(Foo::$foobar);` will still return 10. – tamagokun Dec 15 '11 at 16:27

3 Answers3

0

This is just assigning $test1 to the value of $foobar (which is 5)

$test1 = &$f->bar();

This is just overwriting the value contained in $test1 with 10

$test1 = 10;

If you want to update the value within Foo, use

$f->foobar = 10;
Alec Sanger
  • 4,442
  • 1
  • 33
  • 53
  • This does not answer the question. The question was to return a reference, not to just bypass it completely. – apfelbox Mar 06 '12 at 17:17
0

Doesn't it already work in PHP 5.2.5: http://codepad.org/uMEIK210 (note the 10 as final result)?

I suppose, you would like to see the 10 three times.

For that (that $test2 is also a reference to the class field) you need to specify the & on both sides: function &bar() and $test2 =& Foo::bar();

See the docs:

Note: Unlike parameter passing, here you have to use & in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for $myValue.

So you just need to edit one line to get the (probably) desired 3 x 10:

$test2 =& Foo::bar();

Final hint

Do not use PHP references

apfelbox
  • 2,625
  • 2
  • 24
  • 26
0

First of all, try declaring the function static. Also the call should be a normal call. prefixed by ampersand as already answered.

class Foo
{
    static $foobar = 5;

    public static function &bar()
    {
        return self::$foobar;
    }
}

The call:

$test1 =& Foo::bar();

Also, I can't see a valid reason for referencing a static variable. A static variable is a variable that doesn't change value between calls. It basically is a "global" var enclosed in a namespace. You only need read access from outside the class, the write should be done internally, as per the encapsulation principle. No need for the reference, really..

RedPoppy
  • 573
  • 4
  • 11