Magento有_construct
和__construct
方法的原因吗?为什么存在额外的_construct
?如果只通过调用子类中的父构造函数来实现额外的_construct
方法,可以实现任何目的吗?
答案 0 :(得分:68)
我能找到的最佳答案:http://www.magentocommerce.com/boards/viewthread/76027/#t282659
基本上,根级别类(所有其他类继承的类)实现__construct
,PHP在构造类时自动调用。现在,这个根级类只调用_construct
,其中包含实际代码。
说你有这个设置:
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
doSomethingReallyImportant();
}
}
class SubClass extends BaseClass {
function __construct() {
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
//"In BaseClass constructor"
//something really important happens
$obj = new SubClass();
//"In SubClass constructor"
//important thing DOESN'T happen
PHP不会自动调用父类构造函数,因此永远不会调用doSomethingReallyImportant
。您可以要求子类构造函数调用parent::__construct()
,但这很容易忘记。所以Magento有子类覆盖_construct
:
class BaseClass {
function __construct() {
doSomethingReallyImportant();
_construct();
}
function _construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function _construct() {
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
//something really important happens
//"In BaseClass constructor"
$obj = new SubClass();
//something really important happens
//"In SubClass constructor"
PHP没有在SubClass
中检测到构造函数,因此它调用BaseClass
的构造函数。在调用SubClass的BaseClass
之前,这允许doSomethingReallyImportant
到_construct
。
答案 1 :(得分:4)
To Marco:在Magento中覆盖__construct()
这样的方法是错误的。原因是 - 所有类都从Varien_Object
继承它并且它具有以下代码:
#File: lib/Varien/Object.php
public function __construct()
{
//...snip...
$args = func_get_args();
if (empty($args[0]))
{
$args[0] = array();
}
//...snip...
}
//...
使用__construct使用您的代码,这些参数不会被传递。 你真的必须使用Benesch的代码:
class SubClass extends BaseClass {
function _construct() {
print "In SubClass constructor\n";
}
}
中详细了解此信息
答案 2 :(得分:3)
修改抱歉,错过了您问题中_construct
和__construct
之间的差异。我认为Magento程序员已经尝试使覆盖构造函数变得更容易,而不存在他们自己的构造函数不再被调用的风险。 Varien_Object上的_construct方法是空的,因此如果没有从子类调用它也无关紧要。
这就是PHP如何为类实现构造函数和析构函数。 Magento没有具体的内容。
在其他语言中,构造函数通常使用与类本身具有相同名称的方法实现,构造函数通常在方法名称前面具有波浪号(〜),其名称与类名称相同。出于某种原因,PHP人员已经以这种方式实现了它,尽管PHP似乎也支持具有类名(link)的构造函数和析构函数。
类不必具有构造函数和/或析构函数,尤其是在子类化另一个类时。如果你覆盖了构造函数或析构函数,那么你需要通过在parent::
上调用它来手动调用被覆盖类的构造函数或析构函数,如:
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
// Your code
}
function __destruct() {
// Your code
parent::__destruct();
}
}