2012-01-02 34 views
27

Có lý do gì khiến Magento có một phương thức _construct__construct không? Tại sao có thêm _construct? Bất cứ điều gì có thể đạt được bằng cách có thêm _construct phương pháp không thể đạt được bằng cách chỉ cần gọi constructor cha mẹ trong lớp con?Tại sao Magento có các phương thức _construct và __construct?

+1

bạn có thể hiển thị một ví dụ về điều này? – lonesomeday

+0

Hầu như mọi lớp trong Magento mở rộng lớp 'Varien_Object'. Có PHP '__construct' được định nghĩa ở đó và có' _construct' được định nghĩa. – Nick

Trả lời

63

câu trả lời tốt nhất tôi có thể tìm thấy: http://www.magentocommerce.com/boards/viewthread/76027/#t282659

Về cơ bản, lớp gốc cấp (mà từ đó tất cả các lớp khác kế thừa) thực hiện __construct, mà PHP gọi tự động bất cứ khi nào một lớp học được xây dựng. Ngay bây giờ, lớp cấp cơ sở này chỉ đơn giản gọi là _construct, chứa mã thực tế.

Giả sử bạn có này thiết lập:

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 không tự động gọi constructor của lớp cha mẹ, vì vậy doSomethingReallyImportant bao giờ được gọi. Bạn có thể yêu cầu các nhà xây dựng lớp con gọi parent::__construct(), nhưng điều đó rất dễ quên. Vì vậy, Magento có lớp con ghi đè _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 không phát hiện ra một constructor trong SubClass, vì vậy nó gọi constructor BaseClass 's. Điều này cho phép BaseClass đến doSomethingReallyImportant trước khi gọi số được ghi đè của SubClass _construct.

+1

Đây chính là lý do nó tồn tại. Là một nhà phát triển Magento, bạn nên * không bao giờ * ghi đè phương thức '__construct', vì mọi thứ trong Magento mở rộng' Varien_Object'. Không chắc tại sao điều này chưa được chấp nhận ... – JMTyler

+1

Điều này không đúng đối với tất cả các lớp. Ví dụ, các nhà quan sát sẽ * không * gọi phương thức _construct() một cách tự động. –

+0

Các nhà quan sát là lớp hiếm có trong Magento mà không được yêu cầu (hoặc ít nhất là không bắt buộc) để mở rộng một lớp Varien/Mage. Nếu bạn không mở rộng một lớp Varien cơ sở thì Varien-hành vi gọi _construct() sẽ không xảy ra. – STW

3

Chỉnh sửa: xin lỗi, bỏ qua sự khác biệt giữa _construct__construct trong câu hỏi của bạn. Tôi nghĩ rằng các lập trình viên Magento đã cố gắng để làm cho nó dễ dàng hơn để ghi đè lên các nhà xây dựng mà không có nguy cơ của nhà xây dựng riêng của họ không được gọi nữa. Phương thức _construct trên Varien_Object rỗng vì vậy nó không quan trọng nếu nó không được gọi từ các lớp con.


Đây chỉ là cách PHP triển khai các hàm tạo và hàm hủy cho lớp học. Không có gì Magento cụ thể về nó.

Trong các ngôn ngữ khác, hàm tạo thường được thực hiện với một phương thức có cùng tên với lớp và hàm tạo thường có dấu ngã (~) ở phía trước tên phương thức có cùng tên với lớp. Đối với một số lý do mà người PHP đã thực hiện nó theo cách này mặc dù PHP cũng dường như hỗ trợ các nhà xây dựng và destructors với tên lớp (link).

Một lớp không cần phải có một hàm tạo và/hoặc hàm hủy, đặc biệt khi bạn phân lớp một lớp khác. Nếu bạn làm điều ghi đè lên các nhà xây dựng hoặc destructor thì bạn cần phải gọi constructor hoặc destructor của lớp ghi đè bằng tay bằng cách gọi nó trên parent::, như:

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

Đây phải là câu trả lời đúng ... –

+1

Bản chỉnh sửa thực sự quan trọng và quá dịu. Tôi gần như downvoted câu trả lời này. – kojiro

+0

Nhưng đôi khi nó không được tin tưởng vào kỹ năng lập trình ... – zie1ony

4

Để Marco: nó là sai để ghi đè __construct() phương pháp như thế này trong Magento. Lý do là - tất cả các lớp kế thừa nó từ Varien_Object và nó có mã này:

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

Với __construct sử dụng mã của bạn, những lập luận không được đi qua. Bạn thực sự cần phải sử dụng mã BENESCH của:

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

Đọc thêm về điều này trong Magento Block Lifecycle Methods by Alan Storm

Các vấn đề liên quan