ビヘイビアは、yii\base\Behavior、またはその子クラスのインスタンスです。ビヘイビアは、ミックスインとも呼ばれ、既存のコンポーネントクラスの機能を、クラスの継承を変更することなく拡張することができます。コンポーネントにビヘイビアをアタッチすると、ビヘイビアのメソッドとプロパティがコンポーネントに「注入」され、コンポーネントクラス自体で定義されているかのように、それらのメソッドとプロパティにアクセスできるようになります。さらに、ビヘイビアは、コンポーネントによってトリガーされるイベントに応答することができ、これにより、ビヘイビアはコンポーネントの通常のコード実行をカスタマイズすることもできます。
ビヘイビアを定義するには、yii\base\Behaviorを拡張するクラス、またはその子クラスを拡張するクラスを作成します。例えば
namespace app\components;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
public $prop1;
private $_prop2;
public function getProp2()
{
return $this->_prop2;
}
public function setProp2($value)
{
$this->_prop2 = $value;
}
public function foo()
{
// ...
}
}
上記のコードは、2つのプロパティ`prop1`と`prop2`、そして1つのメソッド`foo()`を持つビヘイビアクラス`app\components\MyBehavior`を定義しています。プロパティ`prop2`は、ゲッター`getProp2()`とセッター`setProp2()`によって定義されていることに注意してください。これは、yii\base\Behaviorがyii\base\BaseObjectを拡張し、したがってゲッターとセッターによるプロパティの定義をサポートしているためです。
このクラスはビヘイビアであるため、コンポーネントにアタッチされると、そのコンポーネントにも`prop1`と`prop2`のプロパティと`foo()`メソッドが追加されます。
ヒント: ビヘイビア内では、yii\base\Behavior::$ownerプロパティを通じて、ビヘイビアがアタッチされているコンポーネントにアクセスできます。
注意: ビヘイビアのyii\base\Behavior::__get()メソッドまたはyii\base\Behavior::__set()メソッド(あるいはその両方)をオーバーライドする場合は、yii\base\Behavior::canGetProperty()メソッドまたはyii\base\Behavior::canSetProperty()メソッド(あるいはその両方)もオーバーライドする必要があります。
ビヘイビアが、アタッチされているコンポーネントによってトリガーされるイベントに応答する必要がある場合は、yii\base\Behavior::events()メソッドをオーバーライドする必要があります。例えば
namespace app\components;
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
// ...
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event)
{
// ...
}
}
events() メソッドは、イベントとその対応するハンドラのリストを返すべきです。上記の例では、EVENT_BEFORE_VALIDATE イベントが存在し、そのハンドラとして beforeValidate()
が定義されていることを宣言しています。イベントハンドラを指定する場合、以下のいずれかの形式を使用できます。
[$object, 'methodName']
イベントハンドラのシグネチャは、以下のようになります。ここで、$event
はイベントパラメータを参照します。イベントの詳細については、イベント のセクションを参照してください。
function ($event) {
}
ビヘイビアは、コンポーネント に静的に、または動的に追加できます。実際には、静的な追加の方が一般的です。
ビヘイビアを静的に追加するには、ビヘイビアを追加するコンポーネントクラスの behaviors() メソッドをオーバーライドします。behaviors() メソッドは、ビヘイビアの 設定 のリストを返す必要があります。各ビヘイビアの設定は、ビヘイビアクラス名または設定配列のいずれかです。
namespace app\models;
use yii\db\ActiveRecord;
use app\components\MyBehavior;
class User extends ActiveRecord
{
public function behaviors()
{
return [
// anonymous behavior, behavior class name only
MyBehavior::class,
// named behavior, behavior class name only
'myBehavior2' => MyBehavior::class,
// anonymous behavior, configuration array
[
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
],
// named behavior, configuration array
'myBehavior4' => [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
]
];
}
}
ビヘイビア設定に対応する配列キーを指定することで、ビヘイビアに名前を関連付けることができます。この場合、ビヘイビアは *名前付きビヘイビア* と呼ばれます。上記の例では、myBehavior2
と myBehavior4
の2つの名前付きビヘイビアがあります。ビヘイビアに名前が関連付けられていない場合、それは *匿名ビヘイビア* と呼ばれます。
ビヘイビアを動的に追加するには、ビヘイビアを追加するコンポーネントの yii\base\Component::attachBehavior() メソッドを呼び出します。
use app\components\MyBehavior;
// attach a behavior object
$component->attachBehavior('myBehavior1', new MyBehavior());
// attach a behavior class
$component->attachBehavior('myBehavior2', MyBehavior::class);
// attach a configuration array
$component->attachBehavior('myBehavior3', [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
]);
yii\base\Component::attachBehaviors() メソッドを使用して、複数のビヘイビアを一度に追加することもできます。
$component->attachBehaviors([
'myBehavior1' => new MyBehavior(), // a named behavior
MyBehavior::class, // an anonymous behavior
]);
以下のように、設定 を 통해 ビヘイビアを追加することもできます。
[
'as myBehavior2' => MyBehavior::class,
'as myBehavior3' => [
'class' => MyBehavior::class,
'prop1' => 'value1',
'prop2' => 'value2',
],
]
詳細については、設定 のセクションを参照してください。
ビヘイビアを使用するには、まず上記の手順に従って コンポーネント に追加します。ビヘイビアがコンポーネントに追加されると、その使用は簡単です。
ビヘイビアの *パブリック* メンバー変数、またはゲッターやセッターで定義された プロパティ には、それが追加されているコンポーネントを 통해 アクセスできます。
// "prop1" is a property defined in the behavior class
echo $component->prop1;
$component->prop1 = $value;
同様に、ビヘイビアの *パブリック* メソッドを呼び出すこともできます。
// foo() is a public method defined in the behavior class
$component->foo();
ご覧のとおり、$component
は prop1
と foo()
を定義していませんが、追加されたビヘイビアにより、コンポーネント定義の一部であるかのように使用できます。
2つのビヘイビアが同じプロパティまたはメソッドを定義し、両方が同じコンポーネントに追加されている場合、プロパティまたはメソッドにアクセスしたときに、コンポーネントに *先に* 追加されたビヘイビアが優先されます。
ビヘイビアは、コンポーネントに追加されるときに名前と関連付けることができます。この場合、名前を使用してビヘイビアオブジェクトにアクセスできます。
$behavior = $component->getBehavior('myBehavior');
コンポーネントに追加されているすべてのビヘイビアを取得することもできます。
$behaviors = $component->getBehaviors();
ビヘイビアを削除するには、ビヘイビアに関連付けられた名前を指定して yii\base\Component::detachBehavior() を呼び出します。
$component->detachBehavior('myBehavior1');
*すべて* のビヘイビアを削除することもできます。
$component->detachBehaviors();
TimestampBehavior
の使用 ¶最後に、yii\behaviors\TimestampBehavior を見てみましょう。このビヘイビアは、insert()
、update()
、または save()
メソッドを 통해 モデルが保存されるたびに、アクティブレコード モデルのタイムスタンプ属性を自動的に更新することをサポートします。
まず、このビヘイビアを使用する予定の アクティブレコード クラスに追加します。
namespace app\models\User;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
class User extends ActiveRecord
{
// ...
public function behaviors()
{
return [
[
'class' => TimestampBehavior::class,
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
// if you're using datetime instead of UNIX timestamp:
// 'value' => new Expression('NOW()'),
],
];
}
}
上記のビヘイビア設定では、レコードが
created_at
属性と updated_at
属性に割り当てる必要があります。updated_at
属性に割り当てる必要があります。**注意:** 上記の実装をMySQLデータベースで動作させるには、UNIXタイムスタンプとするために、カラム(
created_at
、updated_at
)をint(11)として宣言してください。
このコードを使用すると、User
オブジェクトを保存しようとすると、その created_at
と updated_at
が現在のUNIXタイムスタンプで自動的に埋められます。
$user = new User;
$user->email = 'test@example.com';
$user->save();
echo $user->created_at; // shows the current timestamp
TimestampBehavior は、指定された属性に現在のタイムスタンプを割り当て、データベースに保存する便利なメソッド touch() も提供しています。
$user->touch('login_time');
いくつかの組み込みおよび外部ビヘイビアが利用可能です。
ビヘイビアは、プロパティとメソッドをプライマリクラスに「注入」するという点で トレイト と似ていますが、多くの点で異なります。以下で説明するように、どちらも長所と短所があります。代替手段というよりは、互いに補完するものと言えます。
通常のクラスと同様に、ビヘイビアクラスは継承をサポートします。一方、トレイトは、言語でサポートされるコピーアンドペーストと考えることができます。トレイトは継承をサポートしていません。
ビヘイビアは、コンポーネントクラスを変更することなく、コンポーネントに動的に追加および削除できます。トレイトを使用するには、それを使用するクラスのコードを変更する必要があります。
ビヘイビアは設定可能ですが、トレイトは設定できません。
ビヘイビアは、コンポーネントのイベントに応答することで、コンポーネントのコード実行をカスタマイズできます。
同じコンポーネントに追加された異なるビヘイビア間で名前の競合が発生する可能性がある場合、コンポーネントに最初に追加されたビヘイビアを優先することで、競合は自動的に解決されます。異なるトレイトによって発生した名前の競合は、影響を受けるプロパティまたはメソッドの名前を変更することにより、手動で解決する必要があります。
ビヘイビアはオブジェクトであり、時間とメモリの両方を使用するため、トレイトはビヘイビアよりもはるかに効率的です。
トレイトはネイティブ言語構造であるため、IDEはトレイトに対してよりフレンドリーです。
タイプミスを見つけたり、このページの改善が必要だと思いますか?
GitHubで編集してください !
デフォルトのアクションを実行するには、以下のようにinit()関数を宣言します。
コメントするには、サインアップ または ログイン してください。