0

I'm trying to add new PHP Objects to an Array inside a Class. It works for 2 entries but then after adding 1 more the whole array gets destructed.

public $players = array();

This is the Code where I add the new PHP Objects:

    /*
     * $data[0] => GameUserID
     * $data[1] => SlotID (In Game, INT)
     * $data[2] => GameUserName
     * $this => I've made a function called log($str) in the Main class, so I can
     * class this Function in the Player Class later
    */
    $this->log("Creating new player on SlotID #".$data[1]);
    $tmp = new Player($data[0], $data[2], $this);
    $this->players[$data[1]] = &$tmp;
    unset($tmp);

    //$this->players[$data[1]] = new Player($data[0], $data[2], $this);

The Class "Player" does not return anything on __construct().

I can't find the fail I make.

==============

I found out that the variable isn't saving after the function was called (reached the end). It's empty again whenever I call the function again.

  • 1
    Why not just `$this->players[] = new Player($data[0], $data[2], $this)` – Royal Bg Jul 21 '14 at 12:10
  • This happens because you assign a reference (&$tmp) and then you unset the $tmp. so the reference becomes unavailable and further can't be accessed any more. – Valentin Rusk Jul 21 '14 at 12:15
  • It's not about the reference according to me, but about the key `$data[1]`, after each iteration it's never be mcuh different, but let's say only `1` and `2`, which overrides the current index in `$this->players`. – Royal Bg Jul 21 '14 at 12:16
  • @RoyalBg: the $data[1] contains the SlotID which the Player has in the Game, so that I can call the Player object easier instead of going through all the $this->player array and searching for the SlotID. – Littlericket Jul 21 '14 at 12:19
  • @Littlericket what if more than one player is on slot `5` for example. You will end up with code like `$this-players[5] = new Player(....); $this-players[5] = new Player(....);`, which will populate the array only once, you know? – Royal Bg Jul 21 '14 at 12:20
  • @RoyalBg I got two events, one upon joining the Game and one upon leaving. I've planned to destroy the Class upon leaving so I have a unused array index for the next one who joins into this SlotID. A new Player class is made when a Player joins (obv) – Littlericket Jul 21 '14 at 12:23
  • @Littlericket you got two events, so you got 2 keys, which override each other. `$this->player[State One] = new Player(....);` will populate for this state with only one player, despite the times called. You will need a multidimensional array, in order to store in one array the first state, and in another - the other. `$this->players[$data[1]][] = new Player(.....);` – Royal Bg Jul 21 '14 at 12:26

2 Answers2

0

You are passing an object to an array but then you're calling unset() on a variable that points to the object. Note that both variables point to the same object (even if you left out the & operator), so remove your call to unset().

If you prefer, you can also immediately assign the object to your array:

 $this->players[$data[1]] = new Player($data[0], $data[2], $this);

This way, you don't have a $tmp variable in the way. The code isn't harder to understand, in my opinion – on the contrary, $tmp doesn't really express much.


Furthermore, I'm not sure where $data[1] is coming from or what it holds. If you are still having problems, please output all errors during development by putting error_reporting(E_ALL) at the top of your file. This can offer some very valuable insight as to what is going wrong.

Community
  • 1
  • 1
ljacqu
  • 2,132
  • 1
  • 17
  • 21
  • Yea, I've added what $data[1] contains. It contains the SlotID which the Player is using. Removing the & and calling directly a new Player class doenst work either. It still remains with 2 entries in the array, even If i've added more than 2. – Littlericket Jul 21 '14 at 12:13
0

As it got clear from the comments, the OP has only two values (states) in the $data[1] element. Let's call them State One and State Two.

This could result in

$this->players[State One] = new Player($data[0], $data[2], $this);
$this->players[State One] = new Player($data[0], $data[2], $this);
$this->players[State One] = new Player($data[0], $data[2], $this);
$this->players[State Two] = new Player($data[0], $data[2], $this);
$this->players[State Two] = new Player($data[0], $data[2], $this);
$this->players[State Two] = new Player($data[0], $data[2], $this);

Which will result in only 2 elements in the array, as each State One overrides the previous, and each State Two overrides the previous with the same key.

In this case, the solutions are either to create two properties for each state and populate them, or create a multidimensional array:

if ($data[1] === 'State One') {
    $this->playersFromStateOne[] = new Player($data[0], $data[2], $this);
} else {
    $this->playersFromStateTwo[] = new Player($data[0], $data[2], $this);
}

or

$this->players[$data[1]][] = new Player($data[0], $data[2], $this);
Royal Bg
  • 6,988
  • 1
  • 18
  • 24
  • $data[1] contains the SlotID as an integer, which is in a range between 1 and 18. Every player on the server has his own SlotID, and when the player left the game, his SlotID is available for another player again. So that means that i dont have 2 states, i just unset(); the $players[$slotID] var upon quitting the game – Littlericket Jul 21 '14 at 12:35
  • @Littlericket Do you? Can you debug the slot id before creating the object? – Royal Bg Jul 21 '14 at 12:37
  • [link](http://i.imgur.com/oCoe4wZ.png) "Creating new player on SlotID #$data[1]. Ofcourse $data[1] gets intvalidated so that I dont have 0 which will add a random index in the array. As you can see, it creates multiple entries even if he already added a entry before. The thing is that $players don't save somehow, because whenever I var_dump $players at the start of the function its an empty array, and when i var_dump the $players at the end of the function it has the arrays i've added inb4 – Littlericket Jul 21 '14 at 12:44
  • @Littlericket can you show the code where you instantiate the class and invoke the function? Maybe there is the problem, somehow you reset the instance from which class the function is called? – Royal Bg Jul 21 '14 at 13:01
  • http://pastebin.com/5eATy3xF - this is the switch where I gather the Join event and the Quit from the log file. And here's the Player's Class __construct: http://pastebin.com/hiNGgAUT - I came to the conclusion that $this->players resets after the function call is done. But I don't have any clue why that happens. – Littlericket Jul 21 '14 at 14:17
  • Where is this switch done? Is there any possibility the function where this `switch` is in an object which you do reset before each call. Let's say something like `while ($i < 10) { $obj = new Object(); $obj->addPlayers(); $i++; }`. You do expect `addPlayers()` do be called 10 times, but instead you will end up with only one call, because in each `while()` iteration, you recreate the object – Royal Bg Jul 21 '14 at 14:28
  • Nope, its in a function which parses each log file entry. I don't create any other objects in that function, neither in any other functions where I could touch $this->players. As said, the var is resetting itself when the function is done and If I want to access the var from some other function its always an empty Array – Littlericket Jul 21 '14 at 14:33
  • @Littlericket my point was that `$this->players` is in another object, different than `Player`. So is this object created only once? And how does the function is called? Could you provide the code where you call this function :) thanks – Royal Bg Jul 21 '14 at 14:40
  • aight, I've upped them for you [here](https://mega.co.nz/#!5g9QGCrT!Jpi1RKhXyHy97NQP_t_zCBdDA7YtLn1h2clFi7l189o). main.php: L 132 - 137 is the "Join Event", and Line 151 - 154 the "Quit Event" - player.php has the whole Player class in it. – Littlericket Jul 21 '14 at 14:47
  • There are still missing thins as which function calls `run()`, and where is `start()`, I guess complete Worker class is missing – Royal Bg Jul 21 '14 at 14:59
  • Its www.pthreads.org, but that has nothing to do with the main bot class – Littlericket Jul 21 '14 at 15:22
  • I'm still trying to understand how the `run()` method is called. If it's threading is calling it, maybe there is what to do with it ? :) – Royal Bg Jul 21 '14 at 17:47
  • since I'm not using the thread-extension in the main class, what do you search for? its just in the logreader worker class but I don't access the $players in that. – Littlericket Jul 21 '14 at 18:04
  • but the `run()` method calls the method in the main class which is instantiating player object. If the run() method is somehow shared between threads – Royal Bg Jul 21 '14 at 18:08
  • comment out the LogReader on Line 48 / main.php out, then add the bottom of the file do something like `$hcterminal->parse("0:00 J;0100000000000001;0;Player 1"); $hcterminal->parse("0:00 J;0100000000000001;1;Player 2");` and maybe var_dump $players before the JOIN switch and after the JOIN switch, and you'll see that the $players don't save either. – Littlericket Jul 21 '14 at 18:34