마젠토 _construct() vs __construct()

PHP 생성자 __construct()

PHP에서 클래스의 생성자(또는 constructor) “__construct()”는 클래스의 객체 생성시 내부에서 자동으로 호출되며 기본적인 속성들이 초기화 되는 과정을 포함하고 있는 멤버함수 입니다. PHP5에서 생성자는 반드시 필요한 함수는 아니지만 객체가 생성될때 변수가 필요하거나 멤버변수의 초기화가 필요하다면 생성자가 있어야 합니다. 아래의 코드는 PHP 생성자의 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class Product
{
    private $_sku;
    public __construct($sku)
    {
        $this->_sku = $sku;
    }

    public function getSku()
    {
        return $this->_sku;
    }
}

$product = new Product('sample_sku');
echo $product->getSku(); // "sample_sku"를 출력
?>

마젠토 생성자 _construct()

마젠토의 클래스들을 잘 살펴보면 이 생성자 “__construct()” 함수를 찾아보기 힘듭니다. 대신 얼핏보면 생성자 함수처럼 보이는 “_construct()”를 발견할수 있습니다.
두개의 다른점은 일단 보이는대로 언더스코어 “_”가 PHP의 생성자에는 두개가 사용되지만 마젠토의 클래스에서 생성자 역할을 하는 함수에는 언더스코어가 하나밖에 사용되지 않습니다. 결론적으로 마젠토의 생성자 “_construct()”는 PHP 자체에서는 어떤 의미도 가지지 않고, 단지 마젠토에서만 생성자의 역할을 하는 함수일 뿐입니다.
마젠토의 클래스들은 99%(Observer는 제외) “/lib/Varien/Object.php의 “Varien_Object” 클래스에서 상속되었기 때문에 거의 모든 클래스에 “_construct()” 멤버함수가 존재합니다.
“Varien”은 마젠토가 이베이에 인수되기전의 회사이름이었구요, “Varien_Object”는 마젠토 프로그래밍에서 자주 사용되는 get/set/uns 및 마젠토 객체에서 기본적으로 사용되는 속성이나 기능을 가지고 있는 클래스입니다.
아래는 /lib/Varien/Object.php 파일의 생성자 부분만 캡쳐해온 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
class Varien_Object implements ArrayAccess
{
    public function __construct()
    {
        $this->_initOldFieldsMap();
        if ($this->_oldFieldsMap) {
            $this->_prepareSyncFieldsMap();
        }

        $args = func_get_args();
        if (empty($args[0])) {
            $args[0] = array();
        }
        $this->_data = $args[0];
        $this->_addFullNames();

        $this->_construct();
    }

    /**
     * Internal constructor not depended on params. Can be used for object initialization
     */

    protected function _construct()
    {
    }
}
?>

클래스의 생성자를 들여다 보면 생성자 함수의 하단에 “$this->_construct();” 를 발견할수 있습니다.
반면에 “_construct()” 함수는 “생성자가 변수에 의존하지 않으며 객체 생성에 사용된다”는 코멘트와 함께 비어있습니다.
결론적으로 이 “_construct()” 함수는

  • 마젠토 개발 용도로 만들어진 특별한 생성자 함수이며
  • 개발자가 모듈개발을 하거나 기존의 기능을 override 하는 경우 자동으로 Varien_Object 모델을 상속하게 만들어주고
  • 새로 만드는 클래스의 생성자에 “parent::__construct();”를 넣지 않아도 되는 편의성을 제공합니다.

아래의 예제 코드를 보면 조금더 쉽게 이해가 되리라 생각합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
class ParentClass
{
    public function __construct()
    {
        $this->helloWorld();
    }

    public function helloWorld()
    {
        echo "hello world, ";
    }
}

class ChildClass extends ParentClass
{
    public function __construct()
    {
        parent::__construct();
        echo "this is child class";
    }
}

$parent = new ParentClass(); // "hello world, " 를 출력
$child = new ChildClass(); // "hello world, this is child class" 출력
?>

PHP는 자동으로 부모클래스의 생성자를 실행하지 않기 때문에 위의 ChildClass 처럼 ParentClass의 생성자를 override 했을때 “parent::__construct();”를 추가해야만 부모클래스의 생성자를 실행하게 되어 ParentClass::helloworld() 멤버함수를 실행하게 됩니다.
아래는 마젠토 방식의 생성자 예제 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
class ParentClass
{
    public function __construct()
    {
        $this->helloWorld();
        $this->_construct();
    }

    public function helloWorld()
    {
        echo "hello world, ";
    }

    public function _construct()
    {
    }
}

class ChildClass extends ParentClass
{
    public function _construct()
    {
        echo "this is child class";
    }
}

$parent = new ParentClass(); // "hello world, " 출력
$child = new ChildClass(); // "hello world, this is child class" 출력
?>

위의 예제에서 ChildClass에는 PHP 생성자 “__construct()”가 없습니다. 그러므로 자동으로 부모클래스인 ParentClass의 생성자를 실행시키게 되고 ParentClass의 생성자가 필요한 로직을 모두 실행하면서 ChildClass의 _construct()을 실행하게 됩니다.

위의 코드처럼 마젠토에서는 PHP 생성자 “__construct()”를 사용하지 않고 마젠토만의 “_construct()” 함수를 사용함으로써 자동으로 부모클래스의 생성자를 실행시킴과 동시에 “parent::__construct();”를 자식클래스에 포함시키지 않아도 되게끔 만들었습니다. 물론 자식클래스에 PHP 생성자를 만들고 거기에 “parent::__construct()”를 포함시킬 수 있지만 마젠토 개발자라면 “_construct()” 멤버함수를 사용하는게 올바른 마젠토 프로그래밍 방법입니다.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *