An array passed by value or by reference?

Hi! I would like to know in following code

var $a = [1, 2, 3];
var $b = $a;

array $a is passed by value or by reference?



751

Let's look at a simple example.

namespace ExtABC;

class ClassA
{
    public $abc;
    public $def;

    public function __construct()
    {
        let $this->abc = [1, 2, 3];
        let $this->def = $this->abc;

        let $this->abc[0] = 4;
        let $this->abc[1] = 5;
        let $this->abc[2] = 6;
    }
}

When I run the script

<?php

$objectA = new ExtABC\ClassA();
echo " " . $objectA->abc[0];
echo " " . $objectA->abc[1];
echo " " . $objectA->abc[2];
echo " " . $objectA->def[0];
echo " " . $objectA->def[1];
echo " " . $objectA->def[2];

?>

I get the result

 4 5 6 1 2 3

This result shows that when I assign an array

var a = [1, 2, 3];
var b = a;

array passed by value, i.e. in the variable b is created clone of the array a.



751

Well, with this we understand. But then the next question.

Let's add to the expansion ExtABC a class ClassB

namespace ExtABC;
use ExtABC\ClassA;

class ClassB
{
    protected $objectA;

    public function __construct()
    {
        let $this->objectA = new \ExtABC\ClassA();
        let $this->objectA->abc[0] = 7;
    }
}

I am just creating in the class ClassB an object of the class ClassA and I am reading from created object $objectA element of array $abc[0].

During compilation I get an error

Syntax error in extabc/classb on line 11

        let $this->objectA->abc[0] = 7;
--------------------------^

That is, before I read the element of array $abc I need to get a reference to the $objectA. But how to do that? Zephir has no references and an assignment of an array passes the array by value...

One way that seems possible is to first assign it to a temporary variable and then update that variable. PHP always passes objects around by reference, so it should work. However, it will probably throw warnings when compiling about variables never being used:

class ClassB
{
    protected $objectA;

    public function __construct()
    {
        var tmp;

        let $this->objectA = new ClassA();
        var_dump(this->objectA);

        let tmp = $this->objectA;
        let tmp->abc[0] = 7;
        var_dump($this->objectA);
    }
}

results in:

object(ExtABC\ClassA)#3 (2) {
  ["abc"]=>
  array(3) {
    [0]=>
    int(4)
    [1]=>
    int(5)
    [2]=>
    int(6)
  }
  ["def"]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
}
object(ExtABC\ClassA)#3 (2) {
  ["abc"]=>
  array(3) {
    [0]=>
    int(7)
    [1]=>
    int(5)
    [2]=>
    int(6)
  }
  ["def"]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
}

Would be really nice if it supported this kind of syntax, though:

let ($this->objectA)->abc[0] = 7;