Yii アプリケーションは、一定の仕様に基づいて書かれたオブジェクトであるコンポーネントによって成り立っています。 コンポーネントは CComponent のインスタンスか、派生クラスです。 コンポーネントの使用は大概の場合、プロパティへのアクセスやイベントの発生、ハンドリングを伴います。 基底クラスである CComponent は、どのようにプロパティやイベントの定義を行うかを指定しています。
コンポーネントのプロパティはオブジェクトのパブリックなメンバ変数の様なものです。 値を割り当てたり、読み取る事ができます。以下は例です。
$width=$component->textWidth; // textWidth プロパティを取得 $component->enableCaching=true; // enableCaching プロパティをセット
コンポーネントのプロパティを定義するためには、単純にコンポーネントクラスの中でパブリックなメンバ変数を宣言すれば十分です。 しかし、もっと柔軟なやり方は、下記の様に getter や setter メソッドを定義する方法です:
public function getTextWidth() { return $this->_textWidth; } public function setTextWidth($value) { $this->_textWidth=$value; }
これらのコードは、書き込み可能な textWidth プロパティ (この名前の大文字小文字は区別されません) を定義しています。
プロパティの値を読み取る際は getTextWidth() が呼ばれ、プロパティの値が返されます。
同様に、プロパティに値を書き込む際は setTextWidth() が呼ばれます。
もし setter メソッドが未定義の場合、プロパティは読み取りのみが可能となり、書き込みは例外を発生させるでしょう。
プロパティを定義するのに getter と setter のメソッドを使用すると、
プロパティの読み込みや書き込みの時に追加的なロジック (例えば検証の実行やイベントの発生など) を実行することが出来るという利点があります。
注意: getter/setter メソッドで定義されたプロパティとクラスのメンバ変数には少し違いがあります。 前者では、名前の大文字小文字は区別されませんが、後者では大文字小文字が区別されます。
コンポーネントのイベントは、('event handlers' と呼ばれる) メソッドを値として取る特別なプロパティです。 メソッドをイベントに結びつける (割り当てる) 事によって、イベントが発生した場所から自動的にメソッドが呼ばれることになります。 このように、コンポーネントの振る舞いは、コンポーネントの開発時には予期しなかったであろう動作に改造できます。
コンポーネントのイベントは、on で始まる名前のメソッドを定義する事によって定義されます。
getter/setter メソッドによって定義されるプロパティ名と同様に、イベント名は、大文字小文字を区別しません。
下記のコードは、onClicked イベントを定義しています:
public function onClicked($event) { $this->raiseEvent('onClicked', $event); }
ここで $event は、CEvent のインスタンスまたはその子クラスで、イベントパラメータを表します。
下記の様にして、このイベントにメソッドを結びつけることが出来ます:
$component->onClicked=$callback;
ここで $callback は、有効な PHP のコールバックを参照します。
コールバックは、グローバル関数でも、クラスメソッドでも構いません。
もしクラスメソッドである場合は、コールバックは array($object,'methodName') という配列として与えられなければなりません。
イベントハンドラのシグネチャ (指示の書式) は下記の様な書式でなければなりません:
function methodName($event) { ...... }
ここで $event は (raiseEvent() のコールによって生じる) イベントを表すパラメータです。
$event パラメータは CEvent のインスタンスか、その派生クラスです。
これには、最低限、誰がイベントを発生させたかの情報が含まれることになります。
イベントハンドラは PHP 5.3 以上でサポートされる匿名関数でも構成できます。例えば、
$component->onClicked=function($event) { ...... }
もし今 onClicked() をコールしたとすると、onClicked イベントが (onClicked() の中で) 発生し、
結びついたイベントハンドラが自動的に呼び出されるでしょう。
イベントは複数のハンドラに結びつける事ができます。 イベントが発生した際、ハンドラはイベントに結び付けられた順番で呼び出されます。 もし、あるハンドラが、残りのハンドラが呼び出される事を防ごうとする場合、 $event->handled を true にセットする事が出来ます。
コンポーネントは mixin パターンをサポートします。 コンポーネントに対して、一つまたは複数のビヘイビアをアタッチすることが可能です。 ビヘイビア のオブジェクトをアタッチされると、コンポーネントはビヘイビアの持つメソッドを '継承' することが出来ます。 ここでは、機能の特化 (つまり通常のクラス継承) ではなく、機能の収集が行なわれます。 コンポーネントには複数のビヘイビアをアタッチできるため、'多重継承' を実現することが出来ます。
ビヘイビアクラスは IBehavior インタフェースを実装する必要があります。ほとんどのビヘイビアは CBehavior ベースクラスから継承して作成することが出来ます。 ビヘイビアを モデル にアタッチする必要がある場合は、CModelBehavior または CActiveRecordBehavior から継承しても構いません。これらの基底クラスは、モデルに固有な付加機能を実装しています。
ビヘイビアを使うには、最初にビヘイビアの attach() メソッドを呼出して、コンポーネントにアタッチしなければなりません。 その後、コンポーネントを通してビヘイビアのメソッドを呼ぶことができます。
// $name はコンポーネントの中でビヘイビアを特定するユニークな名前です $component->attachBehavior($name, $behavior); // test() は $behavior のメソッドです $component->test();
アタッチされたビヘイビアは、コンポーネントの通常のプロパティのようにアクセスすることができます。
たとえば tree という名前のビヘイビアがコンポーネントにアタッチされた場合、
このビヘイビアオブジェクトを以下のようにして参照することができます。
$behavior=$component->tree; // $behavior=$component->asa('tree'); // と等価
ビヘイビアを一時的に使用不能にして、メソッドがコンポーネントを通して利用できないようにすることが出来ます。 たとえば、
$component->disableBehavior($name); // 以降の文は例外を起します $component->test(); $component->enableBehavior($name); // これで動きます $component->test();
同じコンポーネントにアタッチされた二つのビヘイビアには同じ名前のメソッドがあるかもしれません。 この場合は最初にアタッチされたビヘイビアのメソッドが優先します。
イベント と組み合せて使われた場合には、ビヘイビアはさらに強力です。 コンポーネントにアタッチされるときに、ビヘイビアは自分のメソッドをコンポーネントのイベントにアタッチすることができます。 そうすることによって、ビヘイビアはコンポーネントの通常の実行フローを監視したり変更したりする機会を得ます。
ビヘイビアのプロパティは、アタッチされているコンポーネントからもアクセス可能です。
このプロパティは、パブリックメンバ変数と、getter/setter で定義されるプロパティの両方を含みます。
例えば、ビヘイビアが xyz というプロパティを持ち、コンポーネント $a にアタッチされている場合、
$a->xyz という式によりビヘイビアのプロパティにアクセスすることができます。
Be the first person to leave a comment
Please login to leave your comment.