国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > PHP > 正文

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

2024-05-04 21:50:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

定義行為

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

  1. namespace app/components; 
  2.  
  3.   
  4.  
  5. use yii/base/Behavior; 
  6.  
  7.   
  8.  
  9. class MyBehavior extends Behavior 
  10.  
  11.  
  12.   public $prop1
  13.  
  14.   
  15.  
  16.   private $_prop2
  17.  
  18.   
  19.  
  20.   public function getProp2() 
  21.  
  22.   { 
  23.  
  24.     return $this->_prop2; 
  25.  
  26.   }  
  27.  
  28.   public function setProp2($value
  29.  
  30.   { 
  31.  
  32.     $this->_prop2 = $value
  33.  
  34.   } 
  35.  
  36.   public function foo() 
  37.  
  38.   { 
  39.  
  40.     // ... 
  41.  
  42.   } 
  43.  

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

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

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

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

  1. namespace app/models; 
  2.  
  3.   
  4.  
  5. use yii/db/ActiveRecord; 
  6.  
  7. use app/Components/MyBehavior; 
  8.  
  9.   
  10.  
  11. class User extends ActiveRecord 
  12.  
  13.  
  14.   public function behaviors() 
  15.  
  16.   { 
  17.  
  18.     return [ 
  19.  
  20.       // 匿名的行為,僅直接給出行為的類(lèi)名稱(chēng) 
  21.  
  22.       MyBehavior::className(), 
  23.  
  24.   
  25.  
  26.       // 名為myBehavior2的行為,也是僅給出行為的類(lèi)名稱(chēng) 
  27.  
  28.       'myBehavior2' => MyBehavior::className(), 
  29.  
  30.   
  31.  
  32.       // 匿名行為,給出了MyBehavior類(lèi)的配置數(shù)組 
  33.  
  34.       [ 
  35.  
  36.         'class' => MyBehavior::className(), 
  37.  
  38.         'prop1' => 'value1'
  39.  
  40.         'prop3' => 'value3'
  41.  
  42.       ], 
  43.  
  44.   
  45.  
  46.       // 名為myBehavior4的行為,也是給出了MyBehavior類(lèi)的配置數(shù)組 
  47.  
  48.       'myBehavior4' => [ 
  49.  
  50.         'class' => MyBehavior::className(), 
  51. //Vevb.com 
  52.         'prop1' => 'value1'
  53.  
  54.         'prop3' => 'value3'
  55.  
  56.       ] 
  57.  
  58.     ]; 
  59.  
  60.   } 
  61.  

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

  1.  
  2.   'as myBehavior2' => MyBehavior::className(), 
  3.  
  4.   'as myBehavior3' => [ 
  5.  
  6.     'class' => MyBehavior::className(), 
  7.  
  8.     'prop1' => 'value1'
  9.  
  10.     'prop3' => 'value3'
  11.  
  12.   ], 
  13.  

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

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

  1. $Component->attachBehaviors([ 
  2.  
  3.   'myBehavior1' => new MyBehavior, // 這是一個(gè)命名行為 
  4.  
  5.   MyBehavior::className(),     // 這是一個(gè)匿名行為 
  6.  
  7. ]); 

這個(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)的方面有:

  1. yii/base/Component::behaviors() 
  2.  
  3. yii/base/Component::ensureBehaviors() 
  4.  
  5. yii/base/Component::attachBehaviorInternal() 
  6.  
  7. 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ù)雜,一句話,只要涉及到類(lèi)的屬性、方法、事件這個(gè)函數(shù)都會(huì)被調(diào)用到。

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

  1. public function ensureBehaviors() 
  2.  
  3.  
  4.   // 為null表示尚未綁定 
  5.  
  6.   // 多說(shuō)一句,為空數(shù)組表示沒(méi)有綁定任何行為 
  7.  
  8.   if ($this->_behaviors === null) { 
  9.  
  10.     $this->_behaviors = []; 
  11.  
  12.     // 遍歷 $this->behaviors() 返回的數(shù)組,并綁定 
  13.  
  14.     foreach ($this->behaviors() as $name => $behavior) { 
  15.  
  16.       $this->attachBehaviorInternal($name$behavior); 
  17.  
  18.     } 
  19.  
  20.   } 
  21.  

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

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

  1. private function attachBehaviorInternal($name$behavior
  2.  
  3.  
  4.   // 不是 Behavior 實(shí)例,說(shuō)是只是類(lèi)名、配置數(shù)組,那么就創(chuàng)建出來(lái)吧 
  5.  
  6.   if (!($behavior instanceof Behavior)) { 
  7.  
  8.     $behavior = Yii::createObject($behavior); 
  9.  
  10.   } 
  11.   
  12.   // 匿名行為 
  13.  
  14.   if (is_int($name)) { 
  15.  
  16.     $behavior->attach($this); 
  17.  
  18.     $this->_behaviors[] = $behavior
  19.   
  20.   // 命名行為 
  21.  
  22.   } else { 
  23.   
  24.     // 已經(jīng)有一個(gè)同名的行為,要先解除,再將新的行為綁定上去。 
  25.  
  26.     if (isset($this->_behaviors[$name])) { 
  27.  
  28.       $this->_behaviors[$name]->detach(); 
  29.  
  30.     } 
  31.  
  32.     $behavior->attach($this); 
  33.  
  34.     $this->_behaviors[$name] = $behavior
  35.  
  36.   } 
  37.  
  38.   return $behavior
  39.  

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

如果 $behavior 參數(shù)并非是一個(gè) Behavior 實(shí)例,就以之為參數(shù),用 Yii::createObject() 創(chuàng)建出來(lái)。

如果以匿名行為的形式綁定行為,那么直接將行為附加在這個(gè)類(lèi)上。

如果是命名行為,先看看是否有同名的行為已經(jīng)綁定在這個(gè)類(lèi)上,如果有,用后來(lái)的行為取代之前的行為。

在 yii/base/Component::attachBehaviorInternal() 中, 以 $this 為參數(shù)調(diào)用了 yii/base/Behavior::attach() 。 從而,引出了跟綁定相關(guān)的最后一個(gè)家伙 yii/base/Behavior::attach() , 這也是前面我們講行為的要素時(shí)沒(méi)講完的。先看看代碼:

  1. public function attach($owner
  2.  
  3.  
  4.   $this->owner = $owner
  5.  
  6.   foreach ($this->events() as $event => $handler) { 
  7.  
  8.     $owner->on($eventis_string($handler) ? [$this$handler] : 
  9.  
  10.       $handler); 
  11.  
  12.   } 
  13.  

上面的代碼干了兩件事:

設(shè)置好行為的 $owner,使得行為可以訪問(wèn)、操作所依附的對(duì)象

遍歷行為中的 events() 返回的數(shù)組,將準(zhǔn)備響應(yīng)的事件,通過(guò)所依附類(lèi)的 on() 綁定到類(lèi)上

總結(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綁定到類(lèi)中去。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 莲花县| 兴安县| 鲁甸县| 通州市| 翁牛特旗| 隆化县| 宜昌市| 临沭县| 宣汉县| 平南县| 山阴县| 重庆市| 昌乐县| 师宗县| 博乐市| 五指山市| 临清市| 盱眙县| 阳城县| 双峰县| 望奎县| 昌江| 高要市| 尤溪县| 陇西县| 宜春市| 天津市| 原阳县| 伊宁市| 山东| 额尔古纳市| 铁岭县| 保康县| 梁山县| 陆河县| 敦化市| 武山县| 绥宁县| 正镶白旗| 察隅县| 盐城市|