为什么有些php类有一个空的init()方法


Why do some php classes have an empty init() method?

例如,在Yii2框架中,yii'filters'AccessControl类重写其父类yii'base'Object中的init()函数。这个Object类又有一个类似这样的构造函数方法:

    Class Object implements Configurable {
        public function __construct($config = [])
        {
            if (!empty($config)) {
                Yii::configure($this, $config);
        }
        $this->init(); // calls the method defined below
        }
    }
// and the definition of this init function ... 
    public function init()
    {
    }

现在,编写这样一个空函数显然没有什么用处,除非有人想用来初始化他/她将来可能需要的一些属性。

但是__construct()方法有完全相同的用途!我需要了解这种init()方法有多大帮助。

原因很简单:他们希望您扩展类

所以你应该做一些类似的事情

class Bob extends Object {
    public function init() {
        $this->setup_something();
    }
}

因此,因为Bob扩展了Object,所以Bob的方法就是被调用的方法。如果不需要初始化某个东西,只需跳过定义,基类就会调用空方法。

这使您不必做一些可能更混乱的事情:覆盖构造函数

class Bob extends Object {
    public function __construct($config = []) {
         $this->setup_something();
    }
}

现在,这很混乱,因为很多人错过了一些关键的东西(在这个例子中,我故意忽略了这一点):父构造函数将不会被调用(您可以通过parent::__construct($config)来做到这一点。)。因此,通过有一个单独的init(),可以完全避免这种混乱。有一种明确的方法可以自己设置。

Yii论坛上对此进行了详细讨论。Yii项目负责人:

init()的原因之一是关于对象(确切地说是组件)的生命周期。

使用init()方法,可以在对象被实例化之后和完全初始化之前配置对象。例如,可以使用应用程序配置来配置应用程序组件。如果您重写它的init()方法,您将确保应用了配置,并且可以安全地检查是否一切就绪。类似的事情也发生在小部件和其他可配置组件上。

即使init()是在构造函数内而不是由另一个对象调用的,它也有意义。例如,在CApplication中,有preInit()和init()。它们设置了应用程序的生命周期,并且可能会被覆盖,以便自定义只在预期的生命周期中发生。

我同意你的观点,方法命名非常重要。在Yii中,init()方法意味着对象已经完全配置好,并且应该在该方法中完成一些额外的初始化工作。

和:

每个函数的存在都应该有原因。在Yii的情况下,init()方法主要用于允许在组件的特定生命周期进行自定义。在您的日历应用程序中,您可能需要也可能不需要init()。如果你打算发布它供公众使用,我建议你在允许定制方面更加保守。也就是说,除非你有充分的理由,否则不要定义init()。一旦你提供了一个受保护的或公共的方法,就意味着你需要在未来的版本中维护它。