欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP的Yii框架中行為的定義與綁定方法講解

 更新時(shí)間:2016年03月18日 15:00:55   投稿:goldensun  
這篇文章主要介紹了PHP的Yii框架中行為的定義與綁定方法,包括對(duì)靜態(tài)方法綁定行為與動(dòng)態(tài)方法綁定行為的講解,需要的朋友可以參考下

定義行為

要定義行為,通過(guò)繼承 yii\base\Behavior 或其子類來(lái)建立一個(gè)類。如:

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

以上代碼定義了行為類 app\components\MyBehavior 并為要附加行為的組件提供了兩個(gè)屬性 prop1 、 prop2 和一個(gè)方法 foo()。注意屬性 prop2 是通過(guò) getter getProp2() 和 setter setProp2() 定義的。能這樣用是因?yàn)?yii\base\Object 是 yii\base\Behavior 的祖先類,此祖先類支持用 getter 和 setter 方法定義屬性

提示:在行為內(nèi)部可以通過(guò) yii\base\Behavior::owner 屬性訪問(wèn)行為已附加的組件。

靜態(tài)方法綁定行為

靜態(tài)綁定行為,只需要重載 yii\base\Component::behaviors() 就可以了。 這個(gè)方法用于描述類所具有的行為。如何描述呢? 使用配置來(lái)描述,可以是Behavior類名,也可以是Behavior類的配置數(shù)組:

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類的配置數(shù)組
      [
        'class' => MyBehavior::className(),
        'prop1' => 'value1',
        'prop3' => 'value3',
      ],

      // 名為myBehavior4的行為,也是給出了MyBehavior類的配置數(shù)組
      'myBehavior4' => [
        'class' => MyBehavior::className(),
        'prop1' => 'value1',
        'prop3' => 'value3',
      ]
    ];
  }
}

還有一個(gè)靜態(tài)的綁定辦法,就是通過(guò)配置文件來(lái)綁定:

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

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

動(dòng)態(tài)方法綁定行為

動(dòng)態(tài)綁定行為,需要調(diào)用 yii\base\Compoent::attachBehaviors():

$Component->attachBehaviors([
  'myBehavior1' => new MyBehavior, // 這是一個(gè)命名行為
  MyBehavior::className(),     // 這是一個(gè)匿名行為
]);

這個(gè)方法接受一個(gè)數(shù)組參數(shù),參數(shù)的含義與上面靜態(tài)綁定行為是一樣一樣的。

在上面的這些例子中,以數(shù)組的鍵作為行為的命名,而對(duì)于沒(méi)有提供鍵名的行為,就是匿名行為。

對(duì)于命名的行為,可以調(diào)用 yii\base\Component::getBehavior() 來(lái)取得這個(gè)綁定好的行為:

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

對(duì)于匿名的行為,則沒(méi)有辦法直接引用了。但是,可以獲取所有的綁定好的行為:

$behaviors = $Component->getBehaviors();

綁定的內(nèi)部原理

只是重載一個(gè) yii\base\Component::behaviors() 就可以這么神奇地使用行為了? 這只是冰山的一角,實(shí)際上關(guān)系到綁定的過(guò)程,有關(guān)的方面有:

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

4個(gè)方法中,Behavior只占其一,更多的代碼,是在Component中完成的。

yii\base\Component::behaviors() 上面講靜態(tài)方法綁定行為時(shí)已經(jīng)提到了,就是返回一個(gè)數(shù)組用于描述行為。 那么 yii\base\Component::ensuerBehaviors() 呢?

這個(gè)方法會(huì)在Component的諸多地方調(diào)用 __get() __set() __isset() __unset() __call() canGetProperty() hasMethod() hasEventHandlers() on() off() 等用到,看到這么多是不是頭疼?一點(diǎn)都不復(fù)雜,一句話,只要涉及到類的屬性、方法、事件這個(gè)函數(shù)都會(huì)被調(diào)用到。

這么眾星拱月,被諸多凡人所需要的 ensureBehaviors() 究竟是何許人也? 就像名字所表明的,他的作用在于“ensure” 。其實(shí)只是確保 behaviors() 中所描述的行為已經(jīng)進(jìn)行了綁定而已:

public function ensureBehaviors()
{
  // 為null表示尚未綁定
  // 多說(shuō)一句,為空數(shù)組表示沒(méi)有綁定任何行為
  if ($this->_behaviors === null) {
    $this->_behaviors = [];

    // 遍歷 $this->behaviors() 返回的數(shù)組,并綁定
    foreach ($this->behaviors() as $name => $behavior) {
      $this->attachBehaviorInternal($name, $behavior);
    }
  }
}

這個(gè)方法主要是對(duì)子類用的, yii\base\Compoent 沒(méi)有任何預(yù)先注入的行為,所以,這個(gè)調(diào)用沒(méi)有用。 但是對(duì)于子類,你可能重載了 yii\base\Compoent::behaviros() 來(lái)預(yù)先注入一些行為。 那么,這個(gè)函數(shù)會(huì)將這些行為先注入進(jìn)來(lái)。

從上面的代碼中,自然就看到了接下來(lái)要說(shuō)的第三個(gè)東東, yii\base\Component\attachBehaviorInternal():

private function attachBehaviorInternal($name, $behavior)
{
  // 不是 Behavior 實(shí)例,說(shuō)是只是類名、配置數(shù)組,那么就創(chuàng)建出來(lái)吧
  if (!($behavior instanceof Behavior)) {
    $behavior = Yii::createObject($behavior);
  }

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

  // 命名行為
  } else {

    // 已經(jīng)有一個(gè)同名的行為,要先解除,再將新的行為綁定上去。
    if (isset($this->_behaviors[$name])) {
      $this->_behaviors[$name]->detach();
    }
    $behavior->attach($this);
    $this->_behaviors[$name] = $behavior;
  }
  return $behavior;
}

首先要注意到,這是一個(gè)private成員。其實(shí)在Yii中,所有后綴為 *Internal 的方法,都是私有的。 這個(gè)方法干了這么幾件事:

如果 $behavior 參數(shù)并非是一個(gè) Behavior 實(shí)例,就以之為參數(shù),用 Yii::createObject() 創(chuàng)建出來(lái)。
如果以匿名行為的形式綁定行為,那么直接將行為附加在這個(gè)類上。
如果是命名行為,先看看是否有同名的行為已經(jīng)綁定在這個(gè)類上,如果有,用后來(lái)的行為取代之前的行為。
在 yii\base\Component::attachBehaviorInternal() 中, 以 $this 為參數(shù)調(diào)用了 yii\base\Behavior::attach() 。 從而,引出了跟綁定相關(guān)的最后一個(gè)家伙 yii\base\Behavior::attach() , 這也是前面我們講行為的要素時(shí)沒(méi)講完的。先看看代碼:

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

上面的代碼干了兩件事:

  • 設(shè)置好行為的 $owner ,使得行為可以訪問(wèn)、操作所依附的對(duì)象
  • 遍歷行為中的 events() 返回的數(shù)組,將準(zhǔn)備響應(yīng)的事件,通過(guò)所依附類的 on() 綁定到類上

總結(jié)

說(shuō)了這么多,關(guān)于綁定,做個(gè)小結(jié):

  • 綁定的動(dòng)作從Component發(fā)起;
  • 靜態(tài)綁定通過(guò)重載 yii\base\Componet::behaviors() 實(shí)現(xiàn);
  • 動(dòng)態(tài)綁定通過(guò)調(diào)用 yii\base\Component::attachBehaviors() 實(shí)現(xiàn);
  • 行為還可以通過(guò)為 Component 配置 as 配置項(xiàng)進(jìn)行綁定;
  • 行為有匿名行為和命名行為之分,區(qū)別在于綁定時(shí)是否給出命名。 命名行為可以通過(guò)其命名進(jìn)行標(biāo)識(shí),從而有針對(duì)性地進(jìn)行解除等操作;
  • 綁定過(guò)程中,后綁定的行為會(huì)取代已經(jīng)綁定的同名行為;
  • 綁定的意義有兩點(diǎn),一是為行為設(shè)置 $owner 。二是將行為中擬響應(yīng)的事件的handler綁定到類中去。

相關(guān)文章

  • PHP輸出緩存ob系列函數(shù)詳解

    PHP輸出緩存ob系列函數(shù)詳解

    ob,輸出緩沖區(qū),是output buffering的簡(jiǎn)稱,而不是output cache。ob用對(duì)了,是能對(duì)速度有一定的幫助,但是盲目的加上ob函數(shù),只會(huì)增加CPU額外的負(fù)擔(dān)
    2014-03-03
  • PHP類的封裝與繼承詳解

    PHP類的封裝與繼承詳解

    類是面向?qū)ο笾械闹匾拍?,而封裝和繼承是面向?qū)ο蟮闹匾攸c(diǎn)。這篇文章我們就重點(diǎn)討論一下封裝、繼承這兩個(gè)特點(diǎn),給出一些列子,供大家學(xué)習(xí)參考。
    2015-09-09
  • PHPExcel內(nèi)存泄漏問(wèn)題解決方法

    PHPExcel內(nèi)存泄漏問(wèn)題解決方法

    這篇文章主要介紹了PHPExcel內(nèi)存泄漏問(wèn)題解決方法,本文先是講解了造成內(nèi)存泄漏的原因,然后給出了解決方法,需要的朋友可以參考下
    2015-01-01
  • PHP5.5和之前的版本empty函數(shù)的不同之處

    PHP5.5和之前的版本empty函數(shù)的不同之處

    這篇文章主要介紹了PHP5.5和之前的版本empty函數(shù)的不同之處,開發(fā)時(shí)需要注意,假如你的本地開發(fā)PHP版本是PHP5.5以上,而服務(wù)器低于PHP5.5,更要注意這個(gè)問(wèn)題,需要的朋友可以參考下
    2014-06-06
  • PHP 中檢查或過(guò)濾IP地址的實(shí)現(xiàn)代碼

    PHP 中檢查或過(guò)濾IP地址的實(shí)現(xiàn)代碼

    網(wǎng)絡(luò)環(huán)境異常復(fù)雜,有時(shí)候我們不得不禁止一些惡意用戶訪問(wèn),禁止的方式有很多種,其中一種就是通過(guò) IP 來(lái)限制,本文提供的方法允許你通過(guò) IP 區(qū)間、CIDR (Classless Inter-Domain Routing)及單個(gè) IP 格式來(lái)檢查或過(guò)濾 IP 地址
    2011-11-11
  • php計(jì)算整個(gè)目錄大小的方法

    php計(jì)算整個(gè)目錄大小的方法

    這篇文章主要介紹了php計(jì)算整個(gè)目錄大小的方法,涉及php針對(duì)目錄操作的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • php中使用PHPExcel讀寫excel(xls)文件的方法

    php中使用PHPExcel讀寫excel(xls)文件的方法

    這篇文章主要介紹了php中使用PHPExcel讀寫excel(xls)文件的方法,phpExcel是常用的用于操作Excel的PHP類庫(kù),應(yīng)用非常廣泛。需要的朋友可以參考下
    2014-09-09
  • PHP生成唯一訂單號(hào)

    PHP生成唯一訂單號(hào)

    這篇文章主要給大家介紹了一位網(wǎng)友PHP生成唯一訂單號(hào)的思路和示例,感覺非常不錯(cuò),需要的朋友可以參考下
    2015-07-07
  • php實(shí)現(xiàn)mysql連接池效果實(shí)現(xiàn)代碼

    php實(shí)現(xiàn)mysql連接池效果實(shí)現(xiàn)代碼

    這篇文章主要介紹了php代碼實(shí)現(xiàn)mysql連接池效果,需要的朋友可以參考下
    2018-01-01
  • 發(fā)款php蜘蛛統(tǒng)計(jì)插件只要有mysql就可用

    發(fā)款php蜘蛛統(tǒng)計(jì)插件只要有mysql就可用

    有時(shí)候我們?yōu)榱丝匆幌轮┲肱佬械那闆r,不得不對(duì)日志進(jìn)行大量的分析,由此想做一款插件可以記錄蜘蛛的情況。在第一次做的時(shí)候,只是記錄下蜘蛛的爬行次數(shù),不大好分析。
    2010-10-10

最新評(píng)論