ThinkPHP框架完全解析六



Hook的實現,已經通過tag,顯示出頁面的trace

Hook裏面只有三個成語函數,無非就是將tag導入,然後在某個適當的位置,調用listen,然後listen就會對這個標籤進行解析,如果存在這個標籤,那麼就調用這個標籤。

這樣,通過這種方法,第三方開發人員就可以非常容易地擴展thinkphp的功能了。

比如:接下來,我們要基於我們以前所寫出的框架,然後實現在app::run這個函數被調用時輸出app::run被調用,然後,再在app::run結束調用時,輸出app::run結束調用這個功能。

首先,是實現我們的hook類,在hook類中,目前只有三個方法,一個是導入,一個監聽,另一個是執行。

<?php

namespace Think;

 

class Hook{

        staticprivate $tags=array();

        

        staticfunction exec($name,$tag,&$params=NULL){

                  if('Behavior'==substr($name,-8)){

                           $tag='run';

                  }

                  $addon=new$name();//實例化

                  return$addon->$tag($params);//調用

        }

        

        

        staticfunction import($data,$recursive=true){

                  if($recursive){//直接覆蓋等於真,直接合並數組便可以

                           self::$tags=array_merge(self::$tags,$data);

                  }else{

                           //如果不是直接覆蓋

                  }

        }

        

        staticfunction listen($tag,&$params=NULL){

                  if(isset(self::$tags[$tag])){//如果存在某個插件

                           foreach(self::$tags[$tag]as $name){

                                    $resule=self::exec($name,$tag,$params);

                           }

                  }

        }

}

然後,再在我們的app:;run方法中,補充上兩條語句。

        staticfunction run(){

                  //環境初始化

                  self::init();

                  Hook::listen('app_begin');

                  self::exec();

                  Hook::listen('app_end');

        }

到後標籤的執行動作我們還需要導入,所以在think.class.php中補充上:

        staticfunction start(){

                  //註冊AUTOLOAD方法

     spl_autoload_register('Think\Think::autoload');

         

          Storage::connect();//storage初始化

          Storage::read();//調用read方法

         

          //讀取核心類庫

          $mode=include MODE_PATH.'common.php';

          foreach($mode['core'] as $file){

              if(is_file($file)){

                       include$file;

              }

          }

         

          //導入標籤

          if(isset($mode['tags'])){

              Hook::import($mode['tags']);

          }

         

          App::run();

        }

然後再在我們的模式中添加tags數組便可以了:

'tags' => array(

       'app_begin'    => array(

           'Behavior\AppStartBehavior',

       ),

       'app_end'      => array(

           'Behavior\AppEndBehavior',

                           )

        )

因爲在hook::exec中,這些行爲也會通過Think::autoload自動導入的,所以路徑會變成是LIB_ATH. 'Behavior\AppStartBehavior',因此,我們需要在Library這個目錄下,創建一個Behavior這個目錄,用來存放這種行爲的文件:


APPEndBehavior類中必須要有run這個函數,因此:

<?php

 

namespace Behavior;

 

class AppEndBehavior{

        functionrun(){

                  echo'APP_end';

        }

}

Start也是類同,運行後效果如圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章