Почему в Magento есть методы построения и конструирования?


Есть ли причина, по которой в Magento есть метод _construct и метод __construct? Почему существует дополнительный _construct? Может ли что-либо быть достигнуто с помощью дополнительного метода _construct, чего нельзя достичь, просто вызвав родительский конструктор в дочернем классе?

Author: Nick, 2012-01-03

3 answers

Лучший ответ, который я могу найти: 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. Это позволяет BaseClass doSomethingReallyImportant перед вызовом переопределенного подкласса _construct.

 65
Author: benesch, 2012-01-02 23:35:01

Марко: неправильно переопределять __construct() подобный метод в Magento. Причина в том, что все классы наследуют его от Varien_Object, и у него есть этот код:

#File: lib/Varien/Object.php 
public function __construct() 
{     
      //...snip...             
      $args = func_get_args();     
      if (empty($args[0])) 
      {         
          $args[0] = array();     
      }     
      //...snip... 
} 
//... 

С __конструкцией, использующей ваш код, эти аргументы не передаются. Вам действительно нужно использовать код Бенеша:

class SubClass extends BaseClass {
   function _construct() {
       print "In SubClass constructor\n";
   }
}

Подробнее об этом читайте в Методы жизненного цикла блоков Magento от Алана Шторма

 4
Author: PICher, 2013-12-05 06:18:26

Редактировать: извините, пропустил разницу между _construct и __construct в вашем вопросе. Я думаю, что программисты Magento попытались упростить переопределение конструктора без риска того, что их собственный конструктор больше не будет вызываться. Метод _construct в Varien_Object пуст, поэтому не имеет значения, вызывается ли он не из подклассов.


Именно так PHP реализует конструкторы и деструкторы для классов. В этом нет ничего особенного для Magento это.

На других языках конструктор обычно реализуется с помощью метода, имеющего то же имя, что и сам класс, и конструктор обычно имеет тильду (~) перед именем метода, открывающую то же имя, что и класс. По какой-то причине люди PHP реализовали это таким образом, хотя PHP, похоже, также поддерживает конструкторы и деструкторы с именем класса (ссылка).

Класс не обязательно должен иметь конструктор и/или деструктор, особенно когда вы подкласс другого класса. Если вы переопределяете конструктор или деструктор, вам нужно вызвать конструктор или деструктор переопределенного класса вручную, вызвав его в parent::, например:

class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();
       // Your code
   }
   function __destruct() {
       // Your code
       parent::__destruct();
   }
}
 3
Author: Marco Miltenburg, 2014-11-18 19:34:47