-2

I am porting C# code to PHP.

However, it seems like PHP ignores the array references. The code below gives out the last element 3 times. How can I fix this?

class Participants
{
    public $name; 
    public $country;
    public $town; 

}

class Test
{
    public function __construct()
    {
        $this->List = array(new Participants());
    }

    public function test()
    {           
        $p = new Participants();

        $p->name = "Harry";
        $p->town = "Washington";
        $p->country = "USA";

        $List[0] = $p;

        $p->name = "Janette";
        $p->town = "Amsterdam";
        $p->country = "Netherlands";

        $List[1] = $p;

        $p->name = "Piotr";
        $p->town = "Moscow";
        $p->country = "Russia";

        $List[2] = $p;

    echo $List[0]->name;
    echo $List[1]->name;
    echo $List[2]->name;
        // this unfortunately ignores the index and echoes 3 times the last element.

    }
}//end Test Class
dtech
  • 13,741
  • 11
  • 48
  • 73
  • 1
    _Or_...you've created one object instead of three and assigned each item of the array to the same thing. Just count how many times you're using `new` and the problem should be clear if you're coming from a C# background – Clive May 24 '14 at 09:45
  • 1
    @user3416660 I removed your paragraph about shift registers etc, as it is irrelevant and incorrect. Please keep your questions short and to the point. Also you constructor `$this->List = array(new Participants());` does not do what you think it does. In PHP you do not need to declare the type of values in the array. `$this->List = array();` is enough. Or even better make it a class variable. – dtech May 24 '14 at 10:02
  • tried this out, but it doesn't solve the problem. With the old constructor, the count() function at least returned the correct number of array elements. Using your shortened constructor, the count function returns zero. – user3416660 May 24 '14 at 10:24
  • fyi, 'var_dump()' displays the exact contents of any variable(s). i.e. var_dump($p, $List) will show you what is actually contained in the variables. – Ryan Vincent May 24 '14 at 10:27

2 Answers2

2

Arrays in PHP are actually ordered hashmaps and they are indexable. Your problem has nothing to do with "indexes being ignored". Your problem is that $List[0], $List[1] and $List[2] are all references to the same object.

lafor
  • 12,472
  • 4
  • 32
  • 35
  • Thanks Filype. This construction however has already worked in C#. When function test() is called only once, the instance $p is also created only once and within this call the various array elements are accessed by index. But if you say PHP arrays are indexeable after all, what then is the right syntax for: $List[0]->name ? – user3416660 May 24 '14 at 10:01
  • That _is_ the right syntax if you want the name property of the first object in your array – Clive May 24 '14 at 10:13
2

Objects are mutable, you only make 1 unique object and change the name/town/country 3 times.

When you assign $p to $List[0] you do not make a copy of the object, but instead give $List[0] a reference to the same object as $p, which you then proceed to alter.

If you want 3 objects you need to make 3 objects:

    $p = new Participants();
    $p->name = "Harry";
    $p->town = "Washington";
    $p->country = "USA";
    $List[0] = $p;

    $p = new Participants();
    $p->name = "Janette";
    $p->town = "Amsterdam";
    $p->country = "Netherlands";
    $List[1] = $p;

    $p = new Participants();
    $p->name = "Piotr";
    $p->town = "Moscow";
    $p->country = "Russia";
    $List[2] = $p;

This works the same in nearly every OOP language BTW, including C#. The difference is that in C# you can define a value type (struct or enumeration) which does make a full copy when assigning. My guess is that the C# Participants is a struct.

dtech
  • 13,741
  • 11
  • 48
  • 73
  • You're a life saver dtech! I totally overlooked this, thanks a lot. And yes, you are absolutely right, I came from a structure in C#, therefore this was not an issue there. – user3416660 May 24 '14 at 10:38