Value objects vs associative arrays in PHP Value objects vs associative arrays in PHP php php

Value objects vs associative arrays in PHP


Under the surface, the two approaches are equivalent. However, you get most of the standard OO benefits when using a class: encapsulation, inheritance, etc.

Also, look at the following examples:

$arr['naem'] = 'John';

is perfectly valid and could be a difficult bug to find.

On the other hand,

$class->setNaem('John');

will never work.


A simple class like this one:

class PersonalData {    protected $firstname;    protected $lastname;    // Getters/setters here}

Has few advantages over an array.

  1. There is no possibility to make some typos. $data['firtsname'] = 'Chris'; will work while $data->setFirtsname('Chris'); will throw en error.
  2. Type hinting: PHP arrays can contain everything (including nothing) while well defined class contains only specified data.

    public function doSth(array $personalData) {    $this->doSthElse($personalData['firstname']); // What if "firstname" index doesn't exist?}public function doSth(PersonalData $personalData) {    // I am guaranteed that following method exists.     // In worst case it will return NULL or some default value    $this->doSthElse($personalData->getFirstname());}
  3. We can add some extra code before set/get operations, like validation or logging:

    public function setFirstname($firstname) {    if (/* doesn't match "firstname" regular expression */) {        throw new InvalidArgumentException('blah blah blah');    }if (/* in debbug mode */) {    log('Firstname set to: ' . $firstname);}$this->firstname = $firstname;}
  4. We can use all the benefits of OOP like inheritance, polymorphism, type hinting, encapsulation and so on...
  5. As mentioned before all of our "structs" can inherit from some base class that provides implementation for Countable, Serializable or Iterator interfaces, so our structs could use foreach loops etc.
  6. IDE support.

The only disadvantage seems to be speed. Creation of an array and operating on it is faster. However we all know that in many cases CPU time is much cheaper than programmer time. ;)


After thinking about it for some time, here's my own answer.

The main thing about preferring value objects over arrays is clarity.

Consider this function:

// Yes, you can specify parameter types in PHPfunction MagicFunction(Fred $fred){    // ...}

versus

function MagicFunction(array $fred){}

The intent is clearer. The function author can enforce his requirement.

More importantly, as the user, I can easily look up what constitutes a valid Fred. I just need to open Fred.php and discover its internals.

There is a contract between the caller and the callee. Using value objects, this contract can be written as syntax-checked code:

class Fred{    public $name;    // ...}

If I used an array, I can only hope my user would read the comments or the documentation:

// IMPORTANT! You need to specify 'name' and 'age'function MagicFunction(array $fred){}