
One of the important interfaces in PHP, which enables us to access the elements of a class as an array manner which is the ArrayAccess interface.
Unlike the used methods when accessing class properties using the arrow -> symbol, PHP provides the ArrayAccess interface. When you implement this interface you must implement the 4 methods provided by the interface as shown in the interface terminology below:
interface ArrayAccess { /* Methods */ public offsetExists(mixed $offset): bool public offsetGet(mixed $offset): mixed public offsetSet(mixed $offset, mixed $value): void public offsetUnset(mixed $offset): void }
As shown in the interface structure there four methods, offsetExists(), offsetGet(), offsetSet(), offsetUnset(). These methods triggered automatically when trying to set a property as an array, check property exists with isset() function and unsetting property using unset() function.
But let’s see first if we have a class like this:
class Container { public $property = 1; }
To use and access the property in this class:
$obj = new Container(); echo $obj->property; // 1
If we attempt to access the property like an array it will trigger an error:
echo $obj['property']; // output Fatal error: Uncaught Error: Cannot use object of type Container as array
Now by modifying the class to implement the ArrayAccess interface like this:
class Container implements ArrayAccess { public $property = 1; }
This time when running the script it show this error:
PHP Fatal error: Class Container contains 4 abstract methods and must therefore be declared abstract or implement the remaining methods (ArrayAccess::offsetExists, ArrayAccess::offsetGet, ArrayAccess::offsetSet, ...)
This error because it request from us that we must implement the four methods that i stated above.
Let’s see how can we implement this interface:
class Container implements ArrayAccess { private $data = []; public function offsetSet($offset, $value) { echo "\n offsetSet triggered<br/>\n"; if (is_null($offset)) { $this->data[] = $value; } else { $this->data[$offset] = $value; } } public function offsetExists($offset) { echo "\n offsetExists triggered<br/>\n"; return isset($this->data[$offset]); } public function offsetUnset($offset) { echo "\n offsetUnset triggered<br/>\n"; unset($this->data[$offset]); } public function offsetGet($offset) { echo "\n offsetGet triggered<br/>\n"; return isset($this->data[$offset]) ? $this->data[$offset] : null; } }
In this code i added a private $data property, then in each of the methods all you have to do is to write and read in the $data property. For example the offsetSet($offset, $value) typically this method writes to the $data array using the passed $offset and $value.
I added an echo statement in each method to see when those methods got triggered in the client code.
$container = new Container(); $container['property1'] = 1; $container['property2'] = 2; $container['property3'] = 3; echo $container['property2'] . "\n"; echo (isset($container['property3']) ? 'yes' : 'no') . "\n"; unset($container['property1']); echo (isset($container['property1']) ? 'yes' : 'no') . "\n"; $container[] = "John"; $container[] = "Acme"; var_dump($container);
// output
offsetSet triggered<br/> offsetSet triggered<br/> offsetSet triggered<br/> offsetGet triggered<br/> 2 offsetExists triggered<br/> yes offsetUnset triggered<br/> offsetExists triggered<br/> no offsetSet triggered<br/> offsetSet triggered<br/> object(Container)#1 (1) { ["data":"Container":private]=> array(4) { ["property2"]=> int(2) ["property3"]=> int(3) [0]=> string(4) "John" [1]=> string(4) "Acme" } }
As shown that the methods triggered at certain points:
- When adding new item in the object using $container[‘property’] = 1 the offsetSet() triggered
- When retrieving an item from the object like echo $container[‘property2’] the offsetGet() triggered.
- When checking for existence of property in the object using isset() the offsetExists() triggered.
- When removing property using unset() function the offsetUnset() triggered.
Someone might ask this is familiar, in fact there is a feature in php oop that seem similar to this which is the magic methods. Yes that’s right there are some magic methods like __set(), __get, __isset() which also triggered automatically. But these methods fired when you access a property using the arrow -> symbol like so:
$obj->property
But what’s the point of accessing an object as an array?
Some frameworks and libraries provides accessing properties in different ways using the traditional arrow -> symbol and the array syntax. Examples in laravel and symfony frameworks the ArrayAccess is mostly used.