2012-12-20 2 views
12

Tôi có một lớp một và khởi tạo nó bằng cách sử mớiSử dụng __clone bằng PHP?

$obja = new a; 

Tôi biết sự khác biệt giữa dưới hai dòng

$obja2 = $ojba; 
$obja2 = clone $obja; 

Nhưng ngay cả khi bạn khai báo hoặc không khai báo __clone trong lớp một là người đầu tiên dòng $ obja2 tham chiếu đến không gian bộ nhớ obja $ và dòng thứ hai tạo ra một bản sao của $ obja. Đến đây thì rõ ràng với tôi.

Vậy tại sao php lại có phương pháp ma thuật __clone? Là nó chỉ để thực hiện một tập hợp các mã được viết bên trong __clone trong khi chúng ta sử dụng $ obja2 = clone $ obja;

Ai đó hãy giúp bạn hiểu rõ hơn về điều đó.

+0

Nó tồn tại để cho phép bạn sao chép bất kỳ trường hợp đối tượng nào được giữ trong đối tượng nếu bạn cần - theo mặc định con trỏ sẽ được sao chép nhưng đối tượng mới sẽ có cùng một phiên bản của đối tượng con. – DaveRandom

+0

@DaveRandom: Bạn có thể giải thích đơn giản hơn một chút không :) có thể là một liên kết hoặc bất kỳ điều gì giải thích rõ hơn về điều này. tôi đã thực hiện googling của tôi – zamil

+1

Hãy xem xét một đối tượng của lớp 'A' với thuộc tính' $ innerB', chứa một thể hiện của lớp 'B'. Khi bạn sao chép thể hiện của 'A', đối tượng mới sẽ có cùng một thể hiện của' B'. Bằng cách sử dụng bản sao, bạn có thể làm '$ this-> innerB = clone $ this-> innerB;' - để bạn có thể nhận được một thể hiện mới của 'B' cho đối tượng mới. Xem xét [this] (http://codepad.viper-7.com/Ngssxa) vs [this] (http://codepad.viper-7.com/51YWiC). – DaveRandom

Trả lời

14
void __clone (void) 

Một khi sao chép hoàn tất, nếu một phương pháp __clone() được xác định, sau đó phương pháp __clone() đối tượng mới được tạo ra sẽ được gọi là, để cho phép bất kỳ thuộc tính cần thiết mà cần phải được thay đổi.

http://php.net/manual/en/language.oop5.cloning.php#object.clone

Vì vậy, có, đó là một callback sau ca phẫu thuật clone đã hoàn tất. Không hơn không kém.

+0

vì vậy các vấn đề mà nó tạo ra là gì nếu tôi không viết __clone() trong một lớp? – zamil

+1

Điều đó phụ thuộc vào những gì bạn muốn/cần làm. Là hành vi mặc định của một hoạt động 'clone' PHP đủ cho những gì bạn muốn làm khi nhân bản đối tượng? Thế thì không cần thiết. Nếu bạn cần làm nhiều thứ hơn để tạo một bản sao "hoàn chỉnh", hãy thêm mã đó vào phương thức gọi lại '__clone'. Ví dụ dưới đây: nếu mỗi đối tượng của bạn cần có một ID duy nhất (biến '$ this-> id' này hoặc một thứ gì đó dọc theo các dòng đó), bạn sẽ cần tạo một ID mới sau khi sao chép để tránh có hai đối tượng giống nhau ID. – deceze

+7

Ví dụ khác: 'clone' tạo ra một" bản sao nông ". Điều này có nghĩa là, chỉ có bản thân đối tượng đó được nhân bản, chứ không phải các liên kết của nó. Vì vậy, nếu đối tượng này của 'A' có liên kết với các đối tượng khác, _must_ là duy nhất giữa các thể hiện khác nhau' A', bạn phải sao chép các liên kết trong '__clone()' quá: '$ this-> otherObject = clone $ this-> otherObject; ' – KingCrunch

9

Từ khóa clone trong PHP đại diện cho bản sao cạn.

Để đạt được một bản sao sâu, bạn cần phải thực hiện các phương pháp kỳ diệu __clone

Nếu bạn sao chép một đối tượng mà có một thành viên mà là một đối tượng của lớp khác với các từ khóa đơn giản clone, bạn sẽ giữ cùng một tham chiếu đến đối tượng thứ hai đó.

Đó là nơi mà bản sao sâu có ích, với một cái gì đó như thế này:

public function __clone() 
{ 
    $this->someOtherObject = clone $this->someOtherObject; 
} 

Với điều đó, bạn đảm bảo clone sẽ sâu, có nghĩa là nó sẽ sao chép các đối tượng thành viên là tốt, thay vì chỉ giữ nguyên tham chiếu ban đầu cho họ.

+3

's/shadow/shallow /' – DaveRandom