Implementing ArrayAccess for Domain Objects

This recipe will show you how to implement ArrayAccess for your domain objects in order to allow more uniform access, for example in templates. In these examples we will implement ArrayAccess on a Layer Supertype for all our domain objects.

このレシピでは、テンプレートなどでより均一なアクセスを許可するために、ドメイン オブジェクトに ArrayAccess を実装する方法を示します。これらの例では、すべてのドメイン オブジェクトのレイヤー スーパータイプに ArrayAccess を実装します。

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:

この実装では、PHP の非常に動的な性質を利用して、実行時にスーパータイプのサブタイプのプロパティに動的にアクセスします。この実装には 2 つの主な注意事項があることに注意してください。

  • It will not work with private fields

    プライベートフィールドでは機能しません

  • It will not go through any getters/setters

    ゲッター/セッターを通過しません

<?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;
    }
}

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:

この実装では、ゲッター/セッターを動的に呼び出します。ここでも PHP の動的な性質を使用して、実行時にスーパータイプからサブタイプのメソッドを呼び出します。この実装には次の注意事項があります。

  • It relies on a naming convention

    命名規則に依存しています

  • The semantics of offsetExists can differ

    offsetExists のセマンティクスは異なる場合があります

  • offsetUnset will not work with typehinted setters

    offsetUnset は typehinted セッターでは機能しません

<?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);
    }
}

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 またはオプション 2 を微調整して、arrayaccess を読み取り専用にすることができます。これにより、各オプションの警告の一部も回避されます。単純に、offsetSet と offsetUnset が例外をスローするようにします (つまり、BadMethodCallException)。

<?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!");
    }
}

Table Of Contents

Previous topic

DQL User Defined Functions

DQL ユーザー定義関数

Next topic

Implementing the Notify ChangeTracking Policy

Notify ChangeTracking ポリシーの実装

This Page

Fork me on GitHub