>  기사  >  백엔드 개발  >  PHP Yii Framework_php 스킬의 동작 정의 및 바인딩 방법에 대한 설명

PHP Yii Framework_php 스킬의 동작 정의 및 바인딩 방법에 대한 설명

WBOY
WBOY원래의
2016-05-16 19:56:25963검색

행동 정의

동작을 정의하려면 yiibaseBehavior 또는 해당 하위 클래스를 상속하여 클래스를 만듭니다. 예:

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()
  {
    // ...
  }
}

위 코드는 동작 클래스 appcomComponentsMyBehavior를 정의하고 동작이 연결될 구성 요소에 대해 두 가지 속성 prop1, prop2 및 foo() 메서드를 제공합니다. prop2 속성은 getter getProp2() 및 setter setProp2()를 통해 정의됩니다. yiibaseObject는 yiibaseBehavior의 조상 클래스이기 때문에 이런 방식으로 사용할 수 있습니다. 이 조상 클래스는 getter 및 setter 메서드를 사용하여 속성 정의를 지원합니다

팁: 동작 내에서 yiibaseBehavior::owner 속성을 통해 동작이 연결된 구성 요소에 액세스할 수 있습니다.

정적 메서드 바인딩 동작

동작을 정적으로 바인딩하려면 yiibaseComponent::behaviors()만 오버로드하면 됩니다. 이 메서드는 클래스의 동작을 설명하는 데 사용됩니다. 그것을 설명하는 방법? Behavior 클래스 이름 또는 Behavior 클래스의 구성 배열일 수 있는 구성을 사용하여 설명합니다.

namespace app\models;

use yii\db\ActiveRecord;
use app\Components\MyBehavior;

class User extends ActiveRecord
{
  public function behaviors()
  {
    return [
      // 匿名的行为,仅直接给出行为的类名称
      MyBehavior::className(),

      // 名为myBehavior2的行为,也是仅给出行为的类名称
      'myBehavior2' => MyBehavior::className(),

      // 匿名行为,给出了MyBehavior类的配置数组
      [
        'class' => MyBehavior::className(),
        'prop1' => 'value1',
        'prop3' => 'value3',
      ],

      // 名为myBehavior4的行为,也是给出了MyBehavior类的配置数组
      'myBehavior4' => [
        'class' => MyBehavior::className(),
        'prop1' => 'value1',
        'prop3' => 'value3',
      ]
    ];
  }
}

구성 파일을 통해 바인딩하는 정적 바인딩 방법도 있습니다.

[
  'as myBehavior2' => MyBehavior::className(),

  'as myBehavior3' => [
    'class' => MyBehavior::className(),
    'prop1' => 'value1',
    'prop3' => 'value3',
  ],
]

동적 메서드 바인딩 동작

동적 바인딩 동작은 yiibaseComponent::attachBehaviors():

를 호출해야 합니다.
$Component->attachBehaviors([
  'myBehavior1' => new MyBehavior, // 这是一个命名行为
  MyBehavior::className(),     // 这是一个匿名行为
]);

이 메소드는 배열 매개변수를 허용하며, 매개변수의 의미는 위의 정적 바인딩 동작과 동일합니다.

위의 예에서는 배열의 키가 동작의 이름으로 사용되며, 키 이름을 제공하지 않는 동작은 익명의 동작입니다.

이름이 지정된 동작의 경우 yiibaseComponent::getBehavior()를 호출하여 바인딩된 동작을 가져올 수 있습니다.

$behavior = $Component->getBehavior('myBehavior2');

익명 활동의 경우 직접 인용할 수 있는 방법이 없습니다. 그러나 모든 바인딩된 동작을 얻을 수 있습니다.

$behaviors = $Component->getBehaviors();

제본 내부 원칙

yiibaseComponent::behaviors()를 오버로드하기만 하면 동작을 마술처럼 사용할 수 있나요? 이는 빙산의 일각에 불과합니다. 실제로 관련 측면은 다음과 같습니다.

yii\base\Component::behaviors()
yii\base\Component::ensureBehaviors()
yii\base\Component::attachBehaviorInternal()
yii\base\Behavior::attach()

동작은 네 가지 메소드 중 하나만 설명하며, 더 많은 코드가 컴포넌트에서 완성됩니다.

yiibaseComponent::behaviors() 정적 메서드 바인딩 동작에 관해 위에서 언급한 것처럼 동작을 설명하는 배열을 반환합니다. yiibaseComponent::ensuerBehaviors()는 어떻습니까?

이 메서드는 구성 요소의 여러 위치에서 사용될 때 __get() __set() __isset() __unset() __call() canGetProperty() hasMethod() hasEventHandlers() on() off() 등을 호출합니다. 두통인가요? 한마디로 이 함수는 클래스의 속성, 메소드 및 이벤트를 포함하는 한 호출됩니다.

그렇게 많은 사람들에게 필요한sureBehaviors()는 누구입니까? 이름에서 알 수 있듯이 그의 역할은 "보장"입니다. 실제로는 Behaviors()에 설명된 동작이 바인딩되었는지 확인하기 위한 것입니다.

public function ensureBehaviors()
{
  // 为null表示尚未绑定
  // 多说一句,为空数组表示没有绑定任何行为
  if ($this->_behaviors === null) {
    $this->_behaviors = [];

    // 遍历 $this->behaviors() 返回的数组,并绑定
    foreach ($this->behaviors() as $name => $behavior) {
      $this->attachBehaviorInternal($name, $behavior);
    }
  }
}

이 메서드는 주로 하위 클래스에 사용됩니다. yiibaseComponent에는 사전 주입 동작이 없으므로 이 호출은 쓸모가 없습니다. 그러나 하위 클래스의 경우 일부 동작을 미리 주입하기 위해 yiibaseComponent::behaviros()를 오버로드할 수 있습니다. 그런 다음 이 함수는 이러한 동작을 먼저 주입합니다.

위 코드를 보면 다음으로 이야기할 세 번째 항목인 yiibaseComponentattachBehaviorInternal():

이 자연스럽게 보입니다.
private function attachBehaviorInternal($name, $behavior)
{
  // 不是 Behavior 实例,说是只是类名、配置数组,那么就创建出来吧
  if (!($behavior instanceof Behavior)) {
    $behavior = Yii::createObject($behavior);
  }

  // 匿名行为
  if (is_int($name)) {
    $behavior->attach($this);
    $this->_behaviors[] = $behavior;

  // 命名行为
  } else {

    // 已经有一个同名的行为,要先解除,再将新的行为绑定上去。
    if (isset($this->_behaviors[$name])) {
      $this->_behaviors[$name]->detach();
    }
    $behavior->attach($this);
    $this->_behaviors[$name] = $behavior;
  }
  return $behavior;
}

가장 먼저 주목해야 할 점은 비공개 회원이라는 점입니다. 실제로 Yii에서는 접미사 *Internal이 붙은 모든 메소드가 비공개입니다. 이 방법은 다음 작업을 수행합니다.

$behavior 매개변수가 Behavior 인스턴스가 아닌 경우 이를 매개변수로 사용하고 Yii::createObject()를 사용하여 생성하세요.
동작을 익명 동작으로 바인딩하는 경우 해당 동작을 이 클래스에 직접 연결하세요.
이름이 지정된 동작인 경우 먼저 이 클래스에 이미 바인딩된 동일한 이름의 동작이 있는지 확인하세요. 그렇다면 이전 동작을 이후 동작으로 바꾸세요.
yiibaseComponent::attachBehaviorInternal()에서 yiibaseBehavior::attach()는 $this를 매개변수로 사용하여 호출됩니다. 따라서 바인딩과 관련된 마지막 사항인 yiibaseBehavior::attach()가 소개되는데, 이는 앞서 동작의 요소에 대해 이야기할 때 이야기를 마치지 못한 것입니다. 먼저 코드를 살펴보겠습니다.

public function attach($owner)
{
  $this->owner = $owner;
  foreach ($this->events() as $event => $handler) {
    $owner->on($event, is_string($handler) ? [$this, $handler] :
      $handler);
  }
}

위 코드는 두 가지 작업을 수행합니다.

  • 동작이 연결된 개체에 액세스하고 작동할 수 있도록 동작의 $owner를 설정합니다.
  • Behavior에서 events()가 반환한 배열을 순회하고, 첨부된 클래스의 on()을 통해 응답할 이벤트를 클래스에 바인딩합니다.

요약

이제 바인딩에 대해 요약해 보겠습니다.

  • 바인딩된 작업은 구성 요소에서 시작됩니다.
  • 정적 바인딩은 yiibaseComponent::behaviors()를 오버로드하여 구현됩니다.
  • 동적 바인딩은 yiibaseComponent::attachBehaviors()를 호출하여 구현됩니다.
  • 구성 요소의 구성 항목을 구성하여 동작을 바인딩할 수도 있습니다.
  • 행동은 익명 행동과 명명된 행동으로 나눌 수 있는데, 바인딩할 때 이름을 부여하는지 여부에 차이가 있습니다. 명명된 동작은 이름으로 식별할 수 있으므로 릴리스와 같은 작업을 대상 방식으로 수행할 수 있습니다.
  • 바인딩 프로세스 중에 나중에 바인딩된 동작은 동일한 이름의 이미 바인딩된 동작을 대체합니다.
  • 바인딩에는 두 가지 의미가 있습니다. 하나는 동작에 대해 $owner를 설정하는 것입니다. 두 번째는 동작에서 응답할 이벤트의 핸들러를 클래스에 바인딩하는 것입니다.
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.