1 フォロワー

クラス yii\behaviors\OptimisticLockBehavior

継承yii\behaviors\OptimisticLockBehavior » yii\behaviors\AttributeBehavior » yii\base\Behavior » yii\base\BaseObject
実装yii\base\Configurable
利用可能なバージョン2.0.16
ソースコード https://github.com/yiisoft/yii2/blob/master/framework/behaviors/OptimisticLockBehavior.php

OptimisticLockBehavior は、optimisticLock() が返すカラム名を使用して、モデルのロックバージョンを自動的にアップグレードします。

楽観的ロックにより、複数のユーザーが同じレコードにアクセスして編集することができ、潜在的な競合を回避できます。あるユーザーが古いデータに基づいてレコードの保存を試みた場合(別のユーザーがデータを変更したため)、StaleObjectException 例外がスローされ、更新または削除はスキップされます。

このビヘイビアを使用するには、まず optimisticLock() に記載されている手順に従って楽観的ロックを有効にし、ロックバージョンを保持するカラム名を ActiveRecord クラスの rules() メソッドから削除し、以下のコードを追加します。

use yii\behaviors\OptimisticLockBehavior;

public function behaviors()
{
    return [
        OptimisticLockBehavior::class,
    ];
}

デフォルトでは、OptimisticLockBehavior は getBodyParam() を使用して送信された値を解析するか、失敗した場合に 0 に設定します。つまり、バージョン属性を持たないリクエストでは、エンティティへの最初の更新が成功する可能性がありますが、そこから先は、リクエストが期待されるバージョン番号を保持していない限り、それ以降の試行は失敗します。

getBodyParam() にバージョン番号が含まれていない場合、モデルクラスの内部使用でもレコードの保存は失敗します。親クラスで optimisticLock() をオーバーライドして楽観的ロックを有効にし、このビヘイビアを持つ子クラスにビヘイビアをアタッチすることで、親モデルを内部使用に結び付けながら、このビヘイビアを持つ子モデルをエンドユーザー入力を受信するコントローラーにリンクすることができます。あるいは、異なるロジックを実装するために、PHP の呼び出し可能オブジェクトで $value プロパティを構成することもできます。

OptimisticLockBehavior は、モデルのバージョンを 1 つ増やす upgrade() というメソッドも提供しています。これは、接続されたクライアント間でエンティティを古いものとしてマークし、クライアントが再度読み込むまで変更を回避する場合に役立ちます。

$model->upgrade();

楽観的ロックの有効化の詳細については、yii\db\BaseActiveRecord::optimisticLock() を参照してください。

公開プロパティ

継承されたプロパティを非表示

プロパティ 説明 定義元
$attributes array $value を介して指定された値で自動的に埋められる属性のリスト。 yii\behaviors\AttributeBehavior
$owner yii\base\Component|null このビヘイビアの所有者 yii\base\Behavior
$preserveNonEmptyValues boolean 空でない属性値を保持するかどうか。 yii\behaviors\AttributeBehavior
$skipUpdateOnClean boolean $owner が変更されていない場合にこのビヘイビアをスキップするかどうか。 yii\behaviors\OptimisticLockBehavior
$value mixed 現在の属性に割り当てられる値。 yii\behaviors\OptimisticLockBehavior

公開メソッド

継承されたメソッドを非表示

メソッド 説明 定義元
__call() クラスメソッドではない名前付きメソッドを呼び出します。 yii\base\BaseObject
__construct() コンストラクタ。 yii\base\BaseObject
__get() オブジェクトプロパティの値を返します。 yii\base\BaseObject
__isset() プロパティが設定されているかどうか(つまり、定義されていて null でないかどうか)をチェックします。 yii\base\BaseObject
__set() オブジェクトプロパティの値を設定します。 yii\base\BaseObject
__unset() オブジェクトプロパティを null に設定します。 yii\base\BaseObject
attach() ビヘイビアオブジェクトをコンポーネントにアタッチします。 yii\behaviors\OptimisticLockBehavior
canGetProperty() プロパティを読み取ることができるかどうかを示す値を返します。 yii\base\BaseObject
canSetProperty() プロパティを設定できるかどうかを示す値を返します。 yii\base\BaseObject
className() このクラスの完全修飾名を返します。 yii\base\BaseObject
detach() ビヘイビアオブジェクトをコンポーネントからデタッチします。 yii\base\Behavior
evaluateAttributes() 属性値を評価し、現在の属性に割り当てます。 yii\behaviors\AttributeBehavior
events() $owner のイベントのイベントハンドラーを宣言します。 yii\behaviors\OptimisticLockBehavior
hasMethod() メソッドが定義されているかどうかを示す値を返します。 yii\base\BaseObject
hasProperty() プロパティが定義されているかどうかを示す値を返します。 yii\base\BaseObject
init() オブジェクトを初期化します。 yii\base\BaseObject
upgrade() バージョン値を 1 つ増やし、データベースに保存します。 yii\behaviors\OptimisticLockBehavior

保護されたメソッド

継承されたメソッドを非表示

メソッド 説明 定義元
getLockAttribute() optimisticLock() で定義されているように、バージョン値を保持するカラム名を返します。 yii\behaviors\OptimisticLockBehavior
getValue() 現在の属性の値を返します。 yii\behaviors\OptimisticLockBehavior

プロパティの詳細

継承されたプロパティを非表示

$skipUpdateOnClean public プロパティ (バージョン 2.0.8 から利用可能)

$owner が変更されていない場合にこのビヘイビアをスキップするかどうか。

public boolean $skipUpdateOnClean false
$value public プロパティ

null の値の場合、getBodyParam() から直接解析されるか、0 に設定されます。

現在の属性に割り当てられる値です。これは、無名関数、配列形式の呼び出し可能関数(例:[$this, 'methodName'])、DB式を表すExpressionオブジェクト(例:new Expression('NOW()'))、スカラー、文字列、または任意の値にすることができます。関数の場合は、関数の戻り値が属性に割り当てられます。関数のシグネチャは次のようになります。

function ($event)
{
    // return value will be assigned to the attribute
}
public mixed $value null

メソッドの詳細

継承されたメソッドを非表示

__call() public メソッド

定義場所: yii\base\BaseObject::__call()

クラスメソッドではない名前付きメソッドを呼び出します。

これはPHPのマジックメソッドであり、未知のメソッドが呼び出された際に暗黙的に呼び出されるため、直接呼び出さないでください。

public mixed __call ( $name, $params )
$name string

メソッド名

$params array

メソッドパラメータ

戻り値 mixed

メソッドの戻り値

例外 yii\base\UnknownMethodException

未知のメソッドを呼び出した場合

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() public メソッド

定義場所: yii\base\BaseObject::__construct()

コンストラクタ。

デフォルトの実装では、次の2つのことを行います。

  • 指定された設定$configを使用してオブジェクトを初期化します。
  • init() を呼び出します。

このメソッドを子クラスでオーバーライドする場合は、

  • コンストラクタの最後の引数を設定配列(ここの$configのように)にすることをお勧めします。
  • コンストラクタの最後に親の実装を呼び出してください。
public void __construct ( $config = [] )
$config array

オブジェクトのプロパティを初期化するために使用される名前と値のペア

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() public メソッド

定義場所: yii\base\BaseObject::__get()

オブジェクトプロパティの値を返します。

これはPHPのマジックメソッドであり、$value = $object->property;を実行した際に暗黙的に呼び出されるため、直接呼び出さないでください。

__set()も参照してください。

public mixed __get ( $name )
$name string

プロパティ名

戻り値 mixed

プロパティの値

例外 yii\base\UnknownPropertyException

プロパティが定義されていない場合

例外 yii\base\InvalidCallException

プロパティが書き込み専用の場合

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}

            
__isset() public メソッド

定義場所: yii\base\BaseObject::__isset()

プロパティが設定されているかどうか(つまり、定義されていて null でないかどうか)をチェックします。

これはPHPのマジックメソッドであり、isset($object->property)を実行した際に暗黙的に呼び出されるため、直接呼び出さないでください。

プロパティが定義されていない場合は、falseが返されることに注意してください。

https://www.php.net/manual/en/function.isset.phpも参照してください。

public boolean __isset ( $name )
$name string

プロパティ名またはイベント名

戻り値 boolean

指定されたプロパティが設定されているかどうか(nullではないか)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() public メソッド

定義場所: yii\base\BaseObject::__set()

オブジェクトプロパティの値を設定します。

これはPHPのマジックメソッドであり、$object->property = $value;を実行した際に暗黙的に呼び出されるため、直接呼び出さないでください。

__get()も参照してください。

public void __set ( $name, $value )
$name string

プロパティ名またはイベント名

$value mixed

プロパティの値

例外 yii\base\UnknownPropertyException

プロパティが定義されていない場合

例外 yii\base\InvalidCallException

プロパティが読み取り専用の場合

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() public メソッド

定義場所: yii\base\BaseObject::__unset()

オブジェクトプロパティを null に設定します。

これはPHPのマジックメソッドであり、unset($object->property)を実行した際に暗黙的に呼び出されるため、直接呼び出さないでください。

プロパティが定義されていない場合は、このメソッドは何もしません。プロパティが読み取り専用の場合は、例外をスローします。

https://www.php.net/manual/en/function.unset.phpも参照してください。

public void __unset ( $name )
$name string

プロパティ名

例外 yii\base\InvalidCallException

プロパティが読み取り専用の場合。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
attach() public メソッド

ビヘイビアオブジェクトをコンポーネントにアタッチします。

デフォルトの実装では、$ownerプロパティを設定し、events()で宣言されているイベントハンドラをアタッチします。このメソッドをオーバーライドする場合は、親の実装を必ず呼び出してください。

public void attach ( $owner )
$owner yii\base\Component

このビヘイビアをアタッチするコンポーネント。

                public function attach($owner)
{
    parent::attach($owner);
    if (empty($this->attributes)) {
        $lock = $this->getLockAttribute();
        $this->attributes = array_fill_keys(array_keys($this->events()), $lock);
    }
}

            
canGetProperty() publicメソッド

定義位置: yii\base\BaseObject::canGetProperty()

プロパティを読み取ることができるかどうかを示す値を返します。

プロパティは、以下の場合に読み取り可能です。

  • 指定された名前と関連付けられたゲッターメソッドがクラスに存在する場合(この場合、プロパティ名はケースインセンシティブです)。
  • 指定された名前のメンバ変数がクラスに存在する場合($checkVars がtrueの場合)。

参照: canSetProperty().

public boolean canGetProperty ( $name, $checkVars true )
$name string

プロパティ名

$checkVars boolean

メンバ変数をプロパティとして扱うかどうか

戻り値 boolean

プロパティを読み取ることができるかどうか

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() publicメソッド

定義位置: yii\base\BaseObject::canSetProperty()

プロパティを設定できるかどうかを示す値を返します。

プロパティは、以下の場合に書き込み可能です。

  • 指定された名前と関連付けられたセッターメソッドがクラスに存在する場合(この場合、プロパティ名はケースインセンシティブです)。
  • 指定された名前のメンバ変数がクラスに存在する場合($checkVars がtrueの場合)。

参照: canGetProperty().

public boolean canSetProperty ( $name, $checkVars true )
$name string

プロパティ名

$checkVars boolean

メンバ変数をプロパティとして扱うかどうか

戻り値 boolean

プロパティを書き込むことができるかどうか

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
className() public staticメソッド
2.0.14以降非推奨。PHP 5.5以降では、代わりに::classを使用してください。

定義位置: yii\base\BaseObject::className()

このクラスの完全修飾名を返します。

public static string className ( )
戻り値 string

このクラスの完全修飾名。

                public static function className()
{
    return get_called_class();
}

            
detach() publicメソッド

定義位置: yii\base\Behavior::detach()

ビヘイビアオブジェクトをコンポーネントからデタッチします。

デフォルトの実装では、$owner プロパティをアンセットし、events() で宣言されたイベントハンドラをデタッチします。このメソッドをオーバーライドする場合は、親の実装を必ず呼び出してください。

public void detach ( )

                public function detach()
{
    if ($this->owner) {
        foreach ($this->_attachedEvents as $event => $handler) {
            $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler);
        }
        $this->_attachedEvents = [];
        $this->owner = null;
    }
}

            
evaluateAttributes() publicメソッド

定義位置: yii\behaviors\AttributeBehavior::evaluateAttributes()

属性値を評価し、現在の属性に割り当てます。

public void evaluateAttributes ( $event )
$event yii\base\Event

                public function evaluateAttributes($event)
{
    if (
        $this->skipUpdateOnClean
        && $event->name == ActiveRecord::EVENT_BEFORE_UPDATE
        && empty($this->owner->dirtyAttributes)
    ) {
        return;
    }
    if (!empty($this->attributes[$event->name])) {
        $attributes = (array) $this->attributes[$event->name];
        $value = $this->getValue($event);
        foreach ($attributes as $attribute) {
            // ignore attribute names which are not string (e.g. when set by TimestampBehavior::updatedAtAttribute)
            if (is_string($attribute)) {
                if ($this->preserveNonEmptyValues && !empty($this->owner->$attribute)) {
                    continue;
                }
                $this->owner->$attribute = $value;
            }
        }
    }
}

            
events() publicメソッド

$owner のイベントのイベントハンドラーを宣言します。

子クラスは、このメソッドをオーバーライドして、$owner コンポーネントのイベントにどのPHPコールバックをアタッチするかを宣言できます。

コールバックは、ビヘイビアがオーナーにアタッチされると$ownerのイベントにアタッチされ、ビヘイビアがコンポーネントからデタッチされるとイベントからデタッチされます。

コールバックには、以下のいずれかを使用できます。

  • このビヘイビアのメソッド: 'handleClick' ([$this, 'handleClick']と同等)
  • オブジェクトメソッド: [$object, 'handleClick']
  • 静的メソッド: ['Page', 'handleClick']
  • 無名関数: function ($event) { ... }

例を以下に示します。

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events ( )
戻り値 array

イベント(配列のキー)と対応するイベントハンドラメソッド(配列の値)。

                public function events()
{
    return Yii::$app->request instanceof \yii\web\Request ? [
        BaseActiveRecord::EVENT_BEFORE_INSERT => 'evaluateAttributes',
        BaseActiveRecord::EVENT_BEFORE_UPDATE => 'evaluateAttributes',
        BaseActiveRecord::EVENT_BEFORE_DELETE => 'evaluateAttributes',
    ] : [];
}

            
getLockAttribute() protectedメソッド (バージョン2.0.16から使用可能)

optimisticLock() で定義されているように、バージョン値を保持するカラム名を返します。

protected string getLockAttribute ( )
戻り値 string

プロパティ名。

例外 yii\base\InvalidCallException

optimisticLock() が正しく設定されていない場合。

                protected function getLockAttribute()
{
    if ($this->_lockAttribute) {
        return $this->_lockAttribute;
    }
    /* @var $owner BaseActiveRecord */
    $owner = $this->owner;
    $lock = $owner->optimisticLock();
    if ($lock === null || $owner->hasAttribute($lock) === false) {
        throw new InvalidCallException("Unable to get the optimistic lock attribute. Probably 'optimisticLock()' method is misconfigured.");
    }
    $this->_lockAttribute = $lock;
    return $lock;
}

            
getValue() protectedメソッド

現在の属性の値を返します。

null の場合、値は getBodyParam() から解析されるか、0に設定されます。

このメソッドは、evaluateAttributes() によって呼び出されます。その戻り値は、トリガーイベントに対応する属性に代入されます。

protected mixed getValue ( $event )
$event yii\base\Event

現在の属性の更新をトリガーするイベント。

戻り値 mixed

属性値

                protected function getValue($event)
{
    if ($this->value === null) {
        $request = Yii::$app->getRequest();
        $lock = $this->getLockAttribute();
        $formName = $this->owner->formName();
        $formValue = $formName ? ArrayHelper::getValue($request->getBodyParams(), $formName . '.' . $lock) : null;
        $input = $formValue ?: $request->getBodyParam($lock);
        $isValid = $input && (new NumberValidator())->validate($input);
        return $isValid ? $input : 0;
    }
    return parent::getValue($event);
}

            
hasMethod() publicメソッド

定義位置: yii\base\BaseObject::hasMethod()

メソッドが定義されているかどうかを示す値を返します。

デフォルトの実装は、PHP関数method_exists()を呼び出します。PHPマジックメソッド__call()を実装した場合は、このメソッドをオーバーライドできます。

public boolean hasMethod ( $name )
$name string

メソッド名

戻り値 boolean

メソッドが定義されているかどうか

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() publicメソッド

定義先: yii\base\BaseObject::hasProperty()

プロパティが定義されているかどうかを示す値を返します。

プロパティは、以下の場合に定義されています。

  • 指定された名前と関連付けられたゲッターまたはセッターメソッドがクラスに存在する場合(この場合、プロパティ名は大小文字を区別しません)。
  • 指定された名前のメンバ変数がクラスに存在する場合($checkVars がtrueの場合)。

参照

public boolean hasProperty ( $name, $checkVars true )
$name string

プロパティ名

$checkVars boolean

メンバ変数をプロパティとして扱うかどうか

戻り値 boolean

プロパティが定義されているかどうか

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
init() publicメソッド

定義先: yii\base\BaseObject::init()

オブジェクトを初期化します。

このメソッドは、オブジェクトが指定された設定で初期化された後、コンストラクタの最後に呼び出されます。

public void init ( )

                public function init()
{
}

            
upgrade() publicメソッド (バージョン2.0.16以降で使用可能)

バージョン値を 1 つ増やし、データベースに保存します。

$model->upgrade();
public void upgrade ( )
例外 yii\base\InvalidCallException

オーナーが新規レコードの場合。

                public function upgrade()
{
    /* @var $owner BaseActiveRecord */
    $owner = $this->owner;
    if ($owner->getIsNewRecord()) {
        throw new InvalidCallException('Upgrading the model version is not possible on a new record.');
    }
    $lock = $this->getLockAttribute();
    $version = $owner->$lock ?: 0;
    $owner->updateAttributes([$lock => $version + 1]);
}