# レジストリの使用法

レジストリは、アプリケーション空間でオブジェクトや変数を保存するためのコンテナです。 変数をレジストリに保存すると、 そのオブジェクトはアプリケーション内でいつでも利用できるようになります。 この仕組みは、グローバルなストレージを使用する代わりに使用できます。

レジストリの典型的な使用法は、Zend_Registry クラスの静的メソッドを用いるものです。 一方、このクラスは配列オブジェクトでもあるので、 配列風のインターフェイスでアクセスすることもできます。

## レジストリへの値の設定

あるエントリをレジストリに保存するには、静的メソッド `set()` を使用します。

### set() メソッドの使用例

    Zend_Registry::set('index', $value);

値としては、オブジェクトや配列、スカラーを指定できます。 レジストリの特定のエントリに保存されている値を変更するには、 `set()` を使用して新しい値を指定します。

インデックスにはスカラー値 (`NULL`、文字列あるいは整数) を指定します。 通常の配列と同じです。

## レジストリからの値の取得

エントリの内容をレジストリから取得するには、静的メソッド `get()` を使用します。

### get() メソッドの使用例

    $value = Zend_Registry::get('index');

`getInstance()` メソッドは、 シングルトンレジストリオブジェクトを返します。 このレジストリオブジェクトは順次処理をすることが可能 (iterable) で、 レジストリ内の値に簡単にアクセスできます。

### レジストリの順次処理の例

    $registry = Zend_Registry::getInstance();

    foreach ($registry as $index => $value) {
        echo "レジストリのインデックス $index に含まれる内容:\n";
        var_dump($value);
    }

## レジストリオブジェクトの作成

静的メソッドを使用して静的なレジストリにアクセスするだけでなく、 直接インスタンスを作成し、それをオブジェクトとして使用することもできます。

静的メソッドでアクセスするレジストリインスタンスは、 単なるインスタンスのひとつであり、静的に格納されています。 そのため、アプリケーション内のどこからでもアクセスできます。

`Zend_Registry` のインスタンスを作成するには、 ごく普通に `new` コンストラクタを使用します。 コンストラクタで `Zend_Registry` のインスタンスを作成する際に連想配列を渡すと、 レジストリのエントリを初期化できるようになります。

### レジストリを作成する例

    $registry = new Zend_Registry(array('index' => $value));

`Zend_Registry` のインスタンスを作成すると、 配列風の方法でアクセスできるようになります。 あるいは、静的メソッド `setInstance()` を使用することで、このインスタンスを `Zend_Registry` のシングルトンインスタンスに設定することもできます。

### シングルトンレジストリの初期化の例

    $registry = new Zend_Registry(array('index' => $value));

    Zend_Registry::setInstance($registry);

`setInstance()` メソッドは、もしすでに 静的レジストリが初期化されている場合に `Zend_Exception` をスローします。

## レジストリへの配列風のアクセス

複数の値を取得したり設定したりする場合は、 配列風の記法でアクセスすると便利でしょう。

### 配列アクセスの例

    $registry = Zend_Registry::getInstance();

    $registry['index'] = $value;

    var_dump( $registry['index'] );

## オブジェクト形式でのレジストリへのアクセス

オブジェクト指向の方式で、 インデックス名をオブジェクトのプロパティとしてアクセスできると便利でしょう。 そうするには、オプション `ArrayObject::ARRAY_AS_PROPS` を指定してレジストリオブジェクトを明示的に作成し、 静的インスタンスを初期化しなければなりません。

`ArrayObject::ARRAY_AS_PROPS` オプションの設定は、 静的レジストリへの最初のアクセスの前に 行う必要があります。

### ArrayObject::ARRAY_AS_PROPS オプションの既知の問題

PHP のバージョンによっては、 `ArrayObject::ARRAY_AS_PROPS` オプションを指定してレジストリを使用するとバグが発生することがあります。

### オブジェクト形式のアクセスの例

    // アプリケーションの起動ファイルでの記述
    $registry = new Zend_Registry(array(), ArrayObject::ARRAY_AS_PROPS)
    Zend_Registry::setInstance($registry);
    $registry->tree = 'apple';

    .
    .
    .

    // アプリケーション内の別の関数で、
    $registry = Zend_Registry::getInstance();

    echo $registry->tree; // "apple" と出力します

    $registry->index = $value;

    var_dump($registry->index);

## インデックスが存在するかどうかの確認

レジストリの特定のインデックスが値を持っているかどうかを調べるには、 静的メソッド `isRegistered()` を使用します。

### isRegistered() メソッドの使用例

    if (Zend_Registry::isRegistered($index)) {
        $value = Zend_Registry::get($index);
    }

レジストリの特定のインデックスが値を持っているかどうかを配列風に調べるには、 通常の配列と同様に `isset()` を使用します。

### isset() メソッドの使用例

    $registry = Zend_Registry::getInstance();

    // 配列風の構文でのアクセス
    if (isset($registry['index'])) {
        var_dump( $registry['index'] );
    }

    // 有効にしていれば、オブジェクト形式でのアクセスも可能です
    if (isset($registry->index)) {
        var_dump( $registry->index );
    }

## レジストリの拡張

静的レジストリは `Zend_Registry` クラスのインスタンスです。 レジストリに何らかの機能を追加したい場合は、 `Zend_Registry` を継承したクラスを作成し、 それを静的レジストリで使用するシングルトンとして指定します。 クラスを指定するには、静的メソッド `setClassName()` を使用します。

このクラスは `Zend_Registry` のサブクラスでなければなりません。

### シングルトンレジストリのクラス名を指定する例

    Zend_Registry::setClassName('My_Registry');

    Zend_Registry::set('index', $value);

最初にレジストリにアクセスした後でクラス名を設定しようとすると、 レジストリは `Zend_Exception` をスローします。静的レジストリのクラス名は、 アプリケーションの起動ファイルで指定することをお勧めします。

## 静的レジストリの削除

通常は不要ですが、レジストリの静的インスタンスを削除することもできます。 その際には、静的メソッド `_unsetInstance()` を使用します。

### データを失うリスク

`_unsetInstance()` を使用すると、 静的レジストリ内の全データが破棄され、 復旧することはできません。

このメソッドを使用するのは、たとえば、 シングルトンレジストリオブジェクトを初期化した後で `setInstance()` や `setClassName()` を使用する場合です。シングルトンインスタンスを削除することで、 シングルトンレジストリオブジェクトを設定した後であっても これらのメソッドを使用できるようになります。特別な場合を除き、 `Zend_Registry` をこの方式で使うことは推奨しません。

### _unsetInstance() メソッドの例

    Zend_Registry::set('index', $value);

    Zend_Registry::_unsetInstance();

    // クラスを変更します
    Zend_Registry::setClassName('My_Registry');

    Zend_Registry::set('index', $value);