Почему в Magento есть методы построения и конструирования?
Есть ли причина, по которой в Magento есть метод _construct
и метод __construct
? Почему существует дополнительный _construct
? Может ли что-либо быть достигнуто с помощью дополнительного метода _construct
, чего нельзя достичь, просто вызвав родительский конструктор в дочернем классе?
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
.
Марко: неправильно переопределять __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 от Алана Шторма
Редактировать: извините, пропустил разницу между _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();
}
}