PHP arrays vs objects

Update 20May16:

After two days of studying the OO array-like tools in PHP, I’m feeling like it doesn’t make sense to try to completely avoid old-school arrays for my project. The right answer may be an intermingling of the two on my ~5 layer deep data structure, using objects only where it makes sense for having associated methods.

This project is a small add-on to a much larger project that made minimal use of OO structure. Perhaps if I had managed things that way from the beginning, it would not feel so onerous to add in 5 new classes for the management of this data.

I’m in the middle of transitioning over to full-fledged OO PHP, and I’m facing a project that requires a pretty detailed, multi-level data structure to be created and then later sorted based on one of the keys.

I just assumed that using a PHP object would be the more sophisticated, forward-thinking way to do this, but I’ve run into a thicket of issues and I’m having my doubts. I’m okay with taking extra steps to build my tree as an object, but I can’t spend a week studying esoteric OO possibilities before I proceed.

So, what are the benefits of sticking to objects for my data structure, rather than using an array? (Ordered by importance to me)

  1. Allows me the option of bundling methods with the data.
  2. Allows strong authentication of the data types/characteristics through the use of a “gate-keeper” setter method. In general, the flexible structure of the array can cause development pain later.
  3. Allows for good hinting support for the properties in an IDE, including whether a property is original or dynamically declared.
  4. Somewhat simpler drop-ins for interspersing my values into strings. (But beware of the two-level problem)
  5. Easier (for you and others) to understand your code later. If you have more than two PHP functions which accept this data as a parameter, use a class. If nothing else, that lets you define

    someFunction(MyProductClass $product) {

    and it’s very clear what your functions expect as input. As you scale out your code and have more functions it will be much easier to know what type of data each function accepts. Seeing

    someFunction($someArrayData) {

    is not nearly as clear.

  6. Object oriented encoding calls upon IDE and PHP language facilities and makes it easier to catch any errors beforehand
  7. Changes to data can have cascading effects (if you use the gatekeepers __get, __set, etc)
  8. Propagates upon update (? – When is this useful?) By default they are passed by reference.
  9. Better for setting default values?

What considerations favor an array over an object?

  1. There are different operations you have to learn for manipulating the data. (e.g., you can’t use array_push) There are tons of array_* functions that can work on arrays, most of which are very fast.

Some stray issues to bear in mind:

  • It seems counterproductive to make the top level of my tree be OO, but then lower levels revert to being arrays. Or vice versa
  • if you have a class, and you want to output to JSON, there’s no reason you can’t define a json_data() method of your class which returns a JSON-ifiable array of the data in the class.
  • Note you can get a lightweight object by casting an array to an object: (object)['foo'=>'bar']. The resulting value has class StdClass, will be JSON-encoded in its entirety by json_encode() and properties can be renamed as easily as array indices (which isn’t always so easy, when it’s accessed indirectly via a variable).
  • Objects are not suitable to hold lists of data, because you always need a key to address them. Arrays can fulfill both functions – hold arbitrary lists, and a data structure.
  • The ArrayObject class allows objects to work as arrays.
  • It’s worth mentioning that if you cast a multidimensional array as an object it only converts the top level to an object. Sub-arrays will still be arrays. To convert an entire multidimensional array to an object do the following:

    $obj = json_decode(json_encode($array));

Here’s what I need, with the possible solutions nested beneath:

  1. create a multi-level branch of info
    • To go down to a second level, do I need another object? Don’t need to but let’s do it for consistency. 100% objects.
  2. push that branch to a top level tree (preferred: with a numerical key, as with a simple array)
    • make a class that extends splHeap
    • how do I push to splHeap?
    • find any nodes that can consolidate with this one. NOPE! SplHeap can’t do any such comparison.
  3. sort the branches by some key, using a pre-existing method
    • setup a compare based on the length of each segment —
    • splHeap will automatically keep them sorted
  4. loop through the branches and read the data
    • probably will want a do-while loop until there’s nothing in top position

Leave a Reply