When should I use stdClass and when should I use an array in php oo code?

PhpOopStdclass

Php Problem Overview


In the middle of a period of big refactorings at work, I wish to introduce stdClass ***** as a way to return data from functions and I'm trying to find non-subjectives arguments to support my decision.

Are there any situations when would it be best to use one instead of the other ??

What benefits would I get to use stdClass instead of arrays ??


Some would say that functions have to be as little and specific to be able to return one single value. My decision to use stdClass is temporal, as I hope to find the right Value Objects for each process on the long run.

Php Solutions


Solution 1 - Php

The usual approach is

  • Use objects when returning a defined data structure with fixed branches:

       $person
         -> name = "John"
         -> surname = "Miller"
         -> address = "123 Fake St"
    
  • Use arrays when returning a list:

        "John Miller"
        "Peter Miller"
        "Josh Swanson"
        "Harry Miller"
    
  • Use an array of objects when returning a list of structured information:

        $person[0]
          -> name = "John"
          -> surname = "Miller"
          -> address = "123 Fake St"
    
        $person[1]
          -> name = "Peter"
          -> surname = "Miller"
          -> address = "345 High St"
    

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.

Therefore, you can use associative arrays over objects for the first and third examples if you want to. I'd say that's really just a question of style and preference.

@Deceze makes a number of good points on when to use an object (Validation, type checking and future methods).

Solution 2 - Php

Using stdClass to fulfill the same function as an array is not very useful IMHO, it just adds the overhead of an object without any real benefit. You're also missing out on many useful array functions (e.g. array_intersect). You should at least create your own class to enable type checking, or add methods to the object to make it worth using an object.

Solution 3 - Php

I don't think there is any reasonable advantage of using a stdClass over an array as long as your sole intention is to return multiple arbitrary datatypes from a function call.

Since you cannot technically return multiple values natively, you have to use a container that can hold all other datatypes available in PHP. That would be either an object or an array.

function fn1() { return array(1,2); }
function fn2() { return array('one' => 1, 'two' => 2); }
function fn3() { return (object) array(1,2); }
function fn4() { return (object) array('one' => 1, 'two' => 2); }

All of the above would work. The array is a tiny negligible fraction faster and less work to type. It also has a clearly defined purpose in contrast to the generic stdClass (which is a bit wishywashy, isnt it). Both only have an implicit interface, so you will have to look at the docs or the function body to know what they will contain.

If you want to use objects at any cost, you could use ArrayObject or SplFixedArray, but if you look at their APIs would you say you need their functionality for the simple task of returning random multiple values? I don't think so. Don't get me wrong though: if you want to use stdClass, then use it. It's not like it would break anything. But you also would not gain anything. To add at least some benefit, you could create a separate class named ReturnValues for this.

Could be a simple tagging class

class ReturnValues {}

or something more functional

class ReturnValues implements Countable
{
    protected $values;
    public function __construct() { $this->values = func_get_args(); }
    public function __get($key) return $this->values[$key]; }
    public function count() { return count($this->values); }
}

Granted, it doesn't do much and getting the values out of it is still done through an implict interface, but at least the class has a more clearly defined responsibility now. You could extend from this class to create ReturnValue objects for particular operations and give those an explicit interface:

class FooReturnValues extends ReturnValues
{
    public function getFoo() { return $this->values['foo']; }
    public function getBar() { return $this->values['foo']; }
}

Now the developer just has to look at the API to know which multiple values foo() will return. Of course, having to write concrete ReturnValue classes for each and every operation that might return multiple values could become tedious quickly. And personally, I find this overengineered for the initial purpose.

Anyway, hope that makes any sense.

Solution 4 - Php

Well, there are 3 differences:

  • they have an identity. which is why the default for passing array arguments is call by value and for objects call by sharing.
  • there is a semantical difference. If you use an object, anyone who reads the code understand, that the value represents the model some sort of entitity, while an array is supposed to act as a collection or a map
  • And last but not least, refactoring becomes signifficantly easier. If you want to use a concrete class rather than stdClass, all you have to do is to instantiate another class. Which also allows you to add methods.

greetz
back2dos

Solution 5 - Php

The only OBJECTIVE vote of confidence I can find is:

json_decode uses stdClass by default so us mortals in userland should use stdClass for similar situations.

Solution 6 - Php

I find stdClass objects over arrays useful when I need to keep my code clean and somewhat sentence-like readable. Take for example function getProperties() which returns a set of properties, say data about a person (name, age, sex). If getProperties() would return an associative array, when you want to use one of the returned properties, you would write two instructions:

$data = getProperties();
echo $data['name'];

On the other hand, if getProperties() returns a stdClass then you could write that in just one instruction:

echo getProperties()->name;

Solution 7 - Php

In tests of array vs stdclass they way php handles dynamic properties is slower then associative arrays. I'm not saying this to argue micro optimization but rather if your going to do this your better off defining a dataclass with no methods and set public properties. Esp if you are using php 5.4+. Under the hood defined properties are mapped directly to a c array with no hashtable where as dynamic ones need to use a hash table.

This has the added bonus of later becoming a full class without any major interface reworking.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonGView Question on Stackoverflow
Solution 1 - PhpPekkaView Answer on Stackoverflow
Solution 2 - PhpdecezeView Answer on Stackoverflow
Solution 3 - PhpGordonView Answer on Stackoverflow
Solution 4 - Phpback2dosView Answer on Stackoverflow
Solution 5 - PhpWilliam EntrikenView Answer on Stackoverflow
Solution 6 - PhpCojocariu AdrianView Answer on Stackoverflow
Solution 7 - PhpbgrohsView Answer on Stackoverflow