0

Okay, so I have an object which can be accessed as:

$this -> users["u-###"]

where ### is replaced with the user's id number. For my specification, I will be accessing one specific user a lot, so I have assigned $this -> my to a specific user id ($this -> users["u-123"] for example).

This has worked for my needs up until I started editing the value assigned to one of these variables. For example:

$this -> users["u-123"] = 12;

does not automatically update $this -> my (it's assignment by value after all). Now, I want to use the & operator to fix this, but the way I assign this value is not very conventional. This is my method:

$this -> my = $this -> get_user(123);

where:

function get_user($id){
    /* some stuff here.... */
    $user = $this -> users["u-" . $id];
    return $user;
}

So I first thought, just update the assignment such that it looks like:

$this -> my = &$this -> get_user(123);

That didn't solve my problem. So I thought of also doing it within the function body as such:

function get_user($id){
    /* some stuff here.... */
    $user = &$this -> users["u-" . $id];
    return $user;
}

but this doesn't solve it either. Is there a way to achieve the reference assignment (so $this -> my and $this -> users["u-123"] both point to the same object with my get_user method?

Keir Simmons
  • 1,634
  • 7
  • 21
  • 37

3 Answers3

0

In fact you have 2 ways of doing it. Consider the following example:

<?php


class A {

    public $my;    
    public $users;
    public $my2;

    public function __construct() {
        $this -> users["u-5"] = 25;
        $this -> users["u-10"] = 16;

    }

    function &get_user($id){
        /* some stuff here.... */
        $user = & $this -> users["u-" . $id];
        return $user;
    } 
    function & get_user2($id) {
        /* some stuff here.... */
        return $this->users['u-'.$id];
    }

    function assign() {
        $this->my = & $this->get_user(5);

    }           

    function assign2() {
        $this->my2 = & $this->get_user(10);

    }      
}



$obj = new A();
$obj->assign();
echo $obj->my."<br />";
echo $obj->users['u-5']."<br />";
$obj->users['u-5'] = 10;
echo $obj->my."<br />";
echo $obj->users['u-5']."<br />";
echo "-------------<br />";
$obj->assign2();
echo $obj->my2."<br />";
echo $obj->users['u-10']."<br />";
$obj->users['u-10'] = 3;
echo $obj->my2."<br />";
echo $obj->users['u-10']."<br />";

In the first case, when you use new variable, you need to reference it also to $this->users['u-'.$id] to make it work. Otherwise $user is a simple copy and you create reference to copy of $this->users['u-'.$id]. But in other case, when you don't user $user variable you should simple return $this->users['u-'.$id] without reference sign and it will work.

You can read more about Returning references

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
0
function &get_user($id){
    /* some stuff here.... */
    $user = &$this -> users["u-" . $id];
    return $user;
}

and

$this -> my = &$this -> get_user($id);

has solved my problem. It seems I needed an & on the function and both assignments.

Keir Simmons
  • 1,634
  • 7
  • 21
  • 37
0

The issue is that you're assigning the value returned by reference, and not a reference to the actual element you want to reference.

Example:

<?php
class A {
    public function __construct() {
        $this->bar = array('u123' => 42);
        $this->foo = &$this->bar['u123'];
        $this->bar['u123'] = 1337;
        var_dump($this->foo);
    }
}

new A();

This outputs 1337, as the value that foo points to was changed. In your code you want to make $this->my a reference to the actual array element you're storing in the class, so:

$this->my = &$this->user['u-123'];
MatsLindh
  • 49,529
  • 4
  • 53
  • 84