You are browsing a version that is no longer maintained. |
Implementing ArrayAccess for Domain Objects
Option 1
In this implementation we will make use of PHPs highly dynamic nature to dynamically access properties of a subtype in a supertype at runtime. Note that this implementation has 2 main caveats:
- It will not work with private fields
- It will not go through any getters/setters
1 <?php
abstract class DomainObject implements ArrayAccess
{
public function offsetExists($offset) {
return isset($this->$offset);
}
public function offsetSet($offset, $value) {
$this->$offset = $value;
}
public function offsetGet($offset) {
return $this->$offset;
}
public function offsetUnset($offset) {
$this->$offset = null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Option 2
In this implementation we will dynamically invoke getters/setters. Again we use PHPs dynamic nature to invoke methods on a subtype from a supertype at runtime. This implementation has the following caveats:
- It relies on a naming convention
- The semantics of offsetExists can differ
- offsetUnset will not work with typehinted setters
1 <?php
abstract class DomainObject implements ArrayAccess
{
public function offsetExists($offset) {
// In this example we say that exists means it is not null
$value = $this->{"get$offset"}();
return $value !== null;
}
public function offsetSet($offset, $value) {
$this->{"set$offset"}($value);
}
public function offsetGet($offset) {
return $this->{"get$offset"}();
}
public function offsetUnset($offset) {
$this->{"set$offset"}(null);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Read-only
You can slightly tweak option 1 or option 2 in order to make array access read-only. This will also circumvent some of the caveats of each option. Simply make offsetSet and offsetUnset throw an exception (i.e. BadMethodCallException).
1 <?php
abstract class DomainObject implements ArrayAccess
{
public function offsetExists($offset) {
// option 1 or option 2
}
public function offsetSet($offset, $value) {
throw new BadMethodCallException("Array access of class " . get_class($this) . " is read-only!");
}
public function offsetGet($offset) {
// option 1 or option 2
}
public function offsetUnset($offset) {
throw new BadMethodCallException("Array access of class " . get_class($this) . " is read-only!");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19