2

Background:

I have a class in this application I'm building whose job is:

  • __construct: $this->data = $this->mongoDB->collection->findOne();
  • Intermediate functions are employed to manipulate the data in tens of different ways each request. One manipulation could trigger one which would trigger another. This allows me to do unlimited updates to the mongo document with just one query, as long as $this->data['_id'] remains the same. This is the only place where data manipulation of this specific collection is allowed.
  • __destruct: $this->monboDB->collection->save($data)
  • Data is then read back, json_encode'd and sent to Javascript to draw the page

Intention:

I intended to delete a member of an array by looping through said array, matching a value within it, and unsetting that. Example:

foreach($this->data['documents'] as $key => $val){
    if($val == $toBeDeleted){
        unset($this->data['documents'][$key];
    }
}

Then, this would be saved to the DB when the script finishes.

Problem:

When javascript reads back the data, rather than having ['a', 'b', 'd'], I had {'0': 'a', '1': 'b', '3': 'd'} - which can't be treated like an array and would pretty much break things.

Kavi Siegel
  • 2,964
  • 2
  • 24
  • 33

1 Answers1

4

I had this question half typed out before my a-hah! moment, so I figured I'd post my own answer to it too for future reference.

In php, an associative array and an array are all the same. You can have out of order keys, nonconsecutive keys, and almost any key that you'd like to use in calling your array member. Most, if not all, php array functions work with any array key. Objects are a totally different thing.

That being said, Javascript doesn't share the same rules for arrays. A javascript array must have consecutive keys starting at zero, otherwise it is an object. MongoDB is similar to Javascript in this way.

When php converts an object to be used in MongoDB or in Javascript, if the php array doesn't follow that rule, it becomes a Javascript object.

The problem was after unsetting an array index, it left a gap, causing nonconsecutive array keys, causing it to become an object. Simple fix would either be array_slice($array, $key, 1) or $array = array_values($array)

Kavi Siegel
  • 2,964
  • 2
  • 24
  • 33
  • JSON arrays must have consecutive keys starting at zero. Javascript arrays can have non integer keys. Although its very frowned upon. See http://stackoverflow.com/questions/1076658/javascript-array-associative-and-indexed – max Apr 08 '14 at 10:58