THINKPHP的_initialize方法

1、PHP中只有__construct方法为构造方法,会自动执行,_initialize方法本身不是构造方法,不会自动执行,只是在thinkphp的Controller.class.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方法。

2、我们经常会看到很多代码继承关系比较复杂,例如

a、ProjectController.class.php

class ProjectController extends UcenterBaseController{

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

b、UcenterBaseController.class.php

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.php

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方法

3、总结

(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构造函数仅仅在创建对象的时候调用一次,跟其它方法调用没有关系。

转载于:https://my.oschina.net/u/1186749/blog/634930

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值