Почему у Magento есть методы _construct и __construct? - PullRequest
28 голосов
/ 03 января 2012

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

Ответы [ 3 ]

68 голосов
/ 03 января 2012

Лучший ответ, который я могу найти: 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.

4 голосов
/ 05 декабря 2013

Марко: неправильно переопределять __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... 
} 
//... 

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

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

Узнайте больше об этом в Методы жизненного цикла блоков Magento от Alan Storm

3 голосов
/ 04 января 2012

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


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

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

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

class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();
       // Your code
   }
   function __destruct() {
       // Your code
       parent::__destruct();
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...