【问题标题】:Why does Magento have _construct and __construct methods?为什么 Magento 有 _construct 和 __construct 方法?
【发布时间】:2012-01-02 23:22:54
【问题描述】:

Magento 有 _construct__construct 方法有什么原因吗?为什么存在额外的_construct?仅通过调用子类中的父构造函数就不能通过额外的_construct 方法实现任何目标吗?

【问题讨论】:

  • 你能举个例子吗?
  • 几乎 Magento 中的每个类都扩展了 Varien_Object 类。那里定义了 PHP __construct,并且定义了 _construct

标签: php design-patterns magento


【解决方案1】:

我能找到的最佳答案: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 的构造函数。这允许BaseClassdoSomethingReallyImportant,然后再调用子类的覆盖_construct

【讨论】:

  • 这正是它存在的原因。作为 Magento 开发人员,您应该永远覆盖 __construct 方法,因为 Magento 中的所有内容都扩展了 Varien_Object。不知道为什么这还没有被接受......
  • 并非所有课程都如此。例如,观察者将不会自动调用 _construct() 方法。
  • 观察者是 Magento 中罕见的类,不应该(或至少不需要)扩展 Varien/Mage 类。如果您不扩展基本 Varien 类,则不会发生调用 _construct() 的 Varien 行为。
【解决方案2】:

致 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";
   }
}

Magento Block Lifecycle Methods by Alan Storm了解更多信息

【讨论】:

    【解决方案3】:

    编辑:抱歉,在您的问题中错过了_construct__construct 之间的区别。我认为 Magento 程序员已经尝试让重写构造函数变得更容易,而不会有不再调用他们自己的构造函数的风险。 Varien_Object 上的 _construct 方法是空的,所以如果它不是从子类调用也没关系。


    这就是 PHP 为类实现构造函数和析构函数的方式。 Magento 并没有什么特别之处。

    在其他语言中,构造函数通常使用与类本身同名的方法来实现,并且构造函数通常在方法名前面有一个波浪号 (~),与类同名。出于某种原因,尽管 PHP 似乎也支持类名 (link) 的构造函数和析构函数,但 PHP 人员以这种方式实现了它。

    一个类不必有构造函数和/或析构函数,尤其是当你子类化另一个类时。如果您确实重写了构造函数或析构函数,那么您需要通过在parent:: 上调用来手动调用被重写类的构造函数或析构函数,例如:

    class SubClass extends BaseClass {
       function __construct() {
           parent::__construct();
           // Your code
       }
       function __destruct() {
           // Your code
           parent::__destruct();
       }
    }
    

    【讨论】:

    • 编辑真的很重要,而且太低调了。我几乎不赞成这个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    相关资源
    最近更新 更多