THINKPHP的_initialize方法

一、PHP中只有__construct方法爲構造方法,會自動執行,_initialize方法自己不是構造方法,不會自動執行,只是在thinkphp的Controller.class.php中咱們能夠看到以下代碼php

public function __construct() {
    Hook::listen('action_begin',$this->config);
    //實例化視圖類
    $this->view     = Think::instance('Think\View');
    //控制器初始化
    if(method_exists($this,'_initialize'))
        $this->_initialize();
}

核心就在於method_exists這一段,典型的父類調用子類的一個方法。所以咱們在有控制器繼承Controller.class.php的時候,例如BaseController.class.php定義了_initialize方法,則會在初始化BaseController這個類的時候自動去調用_initialize方法。thinkphp

二、咱們常常會看到不少代碼繼承關係比較複雜,例如ide

a、ProjectController.class.php函數

class ProjectController extends UcenterBaseController{

    protected function _initialize(){
        $this->model = new ProjectModel();
        parent::_initialize();
    }

b、UcenterBaseController.class.phpthis

class UcenterBaseController extends FrontendBaseController{

    protected function _initialize(){

        decide_terminal();
        $this->tablePrefix = C('DB_PREFIX');

        parent::_initialize();

c、FrontendBaseController.class.php指針

class FrontendBaseController extends BaseController
{

    /**
     * 初始化入口
     */
    protected function _initialize()
    {
        parent::_initialize();
        if(APP_NAME == 'study') {
            set_theme(C('STUDY_THEME')); 
        } else {
            set_theme(C('SITE_INFO.templet'));
        }
    }

d、BaseController.class.phpcode

class BaseController extends Controller {
    
    /**
     * 初始化入口
     */
    protected function _initialize() {
       
        decide_terminal();
        decide_site();

可能你們在碰到這種繼承關係的時候比較暈,多重繼承究竟執行的是哪一個_initialize方法,這個你們都須要注意php的第二個特性,若是父子類均有_initialize()函數,則子類覆蓋了父類的,若是子類沒有而父類有,則子類繼承父類的。在調用子類對象的_initialize()時,不會致使自動調用父類的_initialize(),咱們必須顯示的用parent::_initialize()來調用父類的方法。也就是說程序在初始化Project.class.php方法的時候,發現這個類有了_initialize方法,則不會自動去執行父類UcenterBaseController的,直接執行本身定義的的_initialize,而後_initialize中有parent::_initialize()再去執行UcenterBaseController的_initialize方法,這個裏面再調用parent::_initialize執行。須要注意的一點是:在BaseController.class.php中不要寫parent::_initialize,會直接報錯的,由於Controller.class.php中沒有_initialize方法對象

三、總結繼承

(1)_initialize()函數是在任何方法執行以前,都要執行的,固然也包括_ _construct構造函數,注意,_ _construct這裏是雙劃線,而_initialize()函數是單劃線。
(2)若是父子類均有_initialize()函數,則子類覆蓋了父類的,若是子類沒有而父類有,則子類繼承父類的。在調用子類對象的_initialize()時,不會致使自動調用父類的_initialize()。
(3)默認狀況下,子類的構造函數也不會自動調用父類的構造函數,這一點與Java不一樣。實際編寫子類的構造函數時,通常都要加上父類構造函數的主動調用 parent::_ _construct(),不然會致使子類對象空指針的異常,如Call to a member function assign() on a non-object。
(4)_initialize()函數是在「任何」方法調用以前都要調用的,也就是說若是存在_initialize()函數,調用對象的任何方法都會導 致_initialize()函數的自動調用,而_ _construct構造函數僅僅在建立對象的時候調用一次,跟其它方法調用沒有關係。ci

相關文章
相關標籤/搜索