0

Consider the following code:

class FOO {
  public $v = [];

  function &refv1() {
     return $this->v[1];
  }
  function refv2(&$ref) {
    $ref = &$this->v[2];
  }
}
$FOO = new FOO();

//this works
$acc = &$FOO->refv1();
$acc = '5';
echo $FOO->v[1]; // 5

// this does not work
$bcc = null;
$FOO->refv2($bcc);
$bcc = '10';
echo $FOO->v[2]; // not set!

It's basically the same, but in the first place I return a reference and in the second case I pass it and set it to a ref inside the function. Why doesn't this work, and how can I set a passed reference as an accessor to an array like in the first function?

ANSWER and EXPLANATION:

PHP is very inconsistent in its syntax. You'd might expect that something like

$c = &f();
function &f() {
  return $a[b];
}

is the same as $c = &$a[b]; but it is in fact something like

$a[b] = &$temp;
$c = &$temp;

So, the second function has to be written like this to behave like the first one:

function refv2(&$ref) {
  $ref = $this->v[2];
  $this->v[2] = &$ref;
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
rhavin
  • 1,512
  • 1
  • 12
  • 33
  • PHP is funny about references and arrays. See the accepted answer in the duplicate for why it doesn't work as expected – Machavity May 18 '23 at 12:23
  • "Funny" is absolutely not the word that comes to my mind here. Absolutely inconsistent would be a family friendly way to say it :D – rhavin May 18 '23 at 12:29

1 Answers1

1

I think your intention is to write this:

class FOO {
  public $v = [];

  function &refv1() {
     return $this->v[1];
  }
  function refv2(&$ref) {
    $this->v[2] = &$ref;
  }
}
$FOO = new FOO();

//this works
$acc = &$FOO->refv1();
$acc = '5';
echo $FOO->v[1]; // 5

// this does not work
$bcc = null;
$FOO->refv2($bcc);
$bcc = '10';
echo $FOO->v[2]; // 10

What went wrong with your code? Basically you got $this->v[2] and $ref the wrong way around in the refv2() method. The right side is assigned to the left side, not the other way around. In your code $this->v[2] is never assigned an value.

KIKO Software
  • 15,283
  • 3
  • 18
  • 33
  • "The right side is assigned to the left side" WHAT?? I want to assign $ref as a reference to v[2] and because of that I have to turn around the assignment…?? – rhavin May 18 '23 at 12:27
  • 1
    @rhavin Yeah, [the manual](https://www.php.net/manual/en/language.operators.assignment.php) says: _"It really means that the left operand gets set to the value of the expression on the right."_. I don't often dabble in reference passing, perhaps read the duplicate that Machavity provided as well to fully understand what's going on. – KIKO Software May 18 '23 at 12:33
  • I often just look up things in manuals when they're new to me, because most languages are pretty much the same and I thought i already knew references. I'm absolutely baffled that no one immediately thought: "well, lets make that one the other way around, because an assignment should not work left-to-right!" Thanks for pointing that one out. – rhavin May 18 '23 at 12:45