Dev Notes

Software Development Resources by David Egan.

ArrayAccess PHP Interface


OOP, PHP
David Egan

The PHP ArrayAccess class is an interface that allows objects to be accessed as arrays.

Classes that extend the ArrayAccess interface must include four core methods:

<?php
ArrayAccess {
  /* Methods */
  abstract public boolean offsetExists ( mixed $offset )
  abstract public mixed offsetGet ( mixed $offset )
  abstract public void offsetSet ( mixed $offset , mixed $value )
  abstract public void offsetUnset ( mixed $offset )
}

When the ArrayAccess class is implemented by a child class with the appropriate methods, data held in the resulting object can be accessed using array syntax.

Background: PHP Arrays

Arrays in PHP are really ordered maps - a data type that associates keys and values.

…This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.

PHP Manual

PHP arrays hold groups of values which can be identified by position or an associative index.

Associative array:

<?php
$container = [
  'first'   => 'one',
  'second'  => 2,
  'third'   => 3,
  'fourth'  => 4,
  'fifth'   => 5
];

// To access:
echo $container['first']; // echoes 'one'
?>

Numerically Indexed Array:

<?php
$container = ['foo', 'bar', 'chimi', 'changa'];

// To access (arrays are zero-indexed):
echo $container[0]; // outputs 'foo'
echo $container[2]; // outputs 'chimi'
?>

Background: PHP Objects

PHP Objects incorporate one or more functions (methods) along with data (properties) into a structure called a class. Many objects can be instantiated from a single class - the class simply provides the blueprint for the object. Classes are defined with the class keyword, and new objects are instantiated from classes using the new keyword.

PHP also includes a generic empty class called stdClass - which can be useful for anonymous objects and dynamic properties. This kind of class is useful for storing key-value pairs. You could do this in an array, but value objects have some advantages.

The stdClass class can be used to create stand-alone objects without first defining a class.

Value Object Example:

<?php
$hygiene_obj = new StdClass;
$hygiene_obj->armpits = 'hairy';
$hygiene_obj->feet_status = 'smelly';
echo "<pre>", json_encode($obj, JSON_PRETTY_PRINT), "</pre>";

// Adding more data is just a matter of creating a new class property. E.g.
$hygiene_obj->hands = 'grubby';

Output:

{
    "armpits": "hairy",
    "feet_status": "smelly"
}

The same thing can be achieved by means of an associative array:

<?php
$hygiene_status = [
  'armpits' => 'hairy',
  'feet status' => 'smelly'
];
echo "<pre>", json_encode($hygiene_status, JSON_PRETTY_PRINT), "</pre>";

// To add another element to the array:
$hygiene_status['hands'] = 'grubby';

The output is the same as the object example, though there is more leeway with the key names, which can contain spaces:

{
    "armpits": "hairy",
    "feet status": "smelly"
}

There are a few ways of creating a stdClass object in modern PHP:

<?php
$obj1 = new stdClass;
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[];

Mistake pointed out by Rajesh in comments:

$Object = {}

Array Access

It can sometimes be useful to access objects as arrays. ArrayAccess is a built in interface class that allows this.

The interface requires that extending classes use these methods:

  • ArrayAccess::offsetExists
  • ArrayAccess::offsetGet
  • ArrayAccess::offsetSet
  • ArrayAccess::offsetUnset

The methods allow us to define a handy data container which can be accessed and amended using the array syntax.

ArrayAccess: Simple Implementation

<?php
class Foo implements ArrayAccess {

  public $container = [
    'first'   => 1,
    'second'  => 2,
    'third'   => 3
  ];

  public function offsetExists ($offset) {

    return isset($this->container[$offset]);

  }

  public function offsetGet ($offset) {

    return isset($this->container[$offset]) ? $this->container[$offset] : null;

  }

  public function offsetSet ($offset, $value) {

    if (is_null($offset)) {
      $this->container[] = $value;
    } else {
      $this->container[$offset] = $value;
    }

  }

  public function offsetUnset ($offset) {

    unset($this->container[$offset]);

  }

}

This allows us to access the Object data structure using array syntax:

<?php
  $object = new Foo;
  $object['test key'] = 'value';
  $object['chimi'] = 'changa';
  $object['first'] = 'changed';

The Updated object:

<?php
// Output of var_dump($object)
object(Foo)[1]
  public 'container' =>
    array (size=5)
      'first' => string 'changed' (length=7)
      'second' => int 2
      'third' => int 3
      'test key' => string 'value' (length=5)
      'chimi' => string 'changa' (length=6)

References

See Also:


comments powered by Disqus