Giải thích bản sao nông của nhân bản với ví dụ.

Đôi khi có thể hữu ích hơn nếu tạo một bản sao của

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

3 và chỉ thay đổi những phần liên quan, sau đó tạo lại hoàn toàn. Ví dụ: khi

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

3 có nhiều phụ thuộc hoặc tham số bạn cần cung cấp;

Để tạo một bản sao như vậy, bạn có thể sử dụng từ khóa

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

5 trong PHP. Tuy nhiên, khi bạn tạo một bản sao như vậy, bạn có thể không nhận được một bản sao đầy đủ

Bản sao nông

Khi sao chép một

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

6 đơn giản với một vài biến vô hướng, một bản sao sẽ gần như giống hệt nhau, nhưng nó sẽ là một thể hiện riêng biệt. Vì vậy, khi chúng tôi cập nhật một giá trị trên bản sao thứ hai, nó sẽ chỉ được cập nhật trên phiên bản đó

$object = (object) ['title' => 'Object title'];

$clone = clone $object;

 

var_dump($object == $clone); // true, they are equivalent

var_dump($object === $clone); // false, they not the same instance

 

$clone->title = 'Clone title';

 

var_dump($object->title == $clone->title); // false, the title are no longer the same

Tuy nhiên, khi

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

5 sao chép đối tượng, nó sẽ tạo ra cái được gọi là Bản sao nông. Điều này có nghĩa là nó sẽ giữ nguyên vẹn tất cả các tham chiếu mà đối tượng đó có. Vì vậy, khi bạn có một đối tượng hoặc tham chiếu được lưu trữ trên một tham số, phiên bản của tham chiếu đó sẽ giống nhau cho cả hai bản sao

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

Điều quan trọng cần ghi nhớ khi làm việc với bản sao. Bởi vì điều này rất có thể là sự giám sát khó chịu hoặc một lợi thế rất hữu ích

Bản sao sâu

Nếu bạn cũng cần các đối tượng lồng nhau của mình là một thể hiện mới, thì bạn cần cái được gọi là Bản sao sâu. Điều này có nghĩa là mọi tham chiếu cũng sẽ là một phiên bản mới của tham chiếu đó

Để giải quyết vấn đề này, bạn có thể sử dụng phương thức ma thuật

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

1 trên đối tượng mà bạn đang nhân bản. Phương thức này được gọi trên đối tượng sau khi sao chép được thực hiện, nhưng cũng trước khi đối tượng được trả về. Vì vậy, bạn có thể sử dụng nó để thay đổi bất kỳ tham số nào

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

Trong ví dụ này, chúng tôi đã cập nhật tham số

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

2 bằng một bản sao mới của chính nó. Vì vậy, bây giờ chúng ta không còn tham chiếu đến cùng một đối tượng. Điều này có nghĩa là chúng tôi hiện có một bản sao sâu

Ghi chú. Bạn có nhận thấy chúng tôi đã tham chiếu

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

3 bên trong phương thức

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

1 không?

Một bản sao không được xây dựng

Một điều khác cần lưu ý là phương thức

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

6 không bao giờ được gọi khi một đối tượng được nhân bản. Cũng giống như với

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

7, đối tượng nhân bản được tạo lại từ trạng thái của đối tượng ban đầu;

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

0

Như bạn có thể thấy, tiêu đề mới trên bản sao cũng được sao chép, trong khi chúng ta có thể mong đợi đối tượng được sao chép có tên là

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

8

nhà máy

Không gọi

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

6 khi nhân bản có thể là một tài sản mạnh mẽ. Nó được sử dụng trong rất nhiều lớp học của nhà máy để tránh các cuộc gọi nặng nề có thể được thực hiện. Hãy tưởng tượng một số phụ thuộc nặng nề được tạo trong hàm tạo. Sự phụ thuộc tương tự đó rất có thể là cùng một ví dụ cho mọi bản sao. Bằng cách này, cuộc gọi chỉ được thực hiện một lần và sau đó phiên bản được chia sẻ giữa mọi bản sao

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

3

Trong ví dụ này, chúng tôi tạo một thể hiện

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

0 của lớp

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

1 trong lần gọi

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

2 đầu tiên. Sau đó chúng tôi trả lại một bản sao của trường hợp đó. Mọi cuộc gọi tiếp theo đến phương thức

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

3 sẽ có phiên bản Người dùng, vì vậy chúng tôi chỉ trả về một bản sao. Việc nhân bản một phiên bản duy nhất này để sao chép các phần phụ thuộc của nó còn được gọi là Mẫu nguyên mẫu

Đặt các biến riêng tư trên một bản sao không có $title = 'Object title';$inner = (object) []; $object = (object) [ 'title' => &$title, // The title parameter is now a reference to $title 'inner' => $inner,];$clone = clone $object;$clone->title = 'Clone title'; var_dump($object->title); // "Clone title"var_dump($object->inner === $clone->inner); // true, the same instance1

Một mẹo hay cuối cùng là bạn thực sự có thể tạo một bản sao và sau đó đặt biến

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

5 trên bản sao đó mà không cần sử dụng phương thức

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

1. Để làm điều này, bạn phải tạo một phương thức trên lớp đối tượng để tạo bản sao và trả về nó. Bên trong phương thức này, bạn vẫn có thể cập nhật các biến riêng tư của phiên bản nhân bản

$title = 'Object title';

$inner = (object) [];

 

$object = (object) [

'title' => &$title, // The title parameter is now a reference to $title

'inner' => $inner,

];

$clone = clone $object;

$clone->title = 'Clone title';

 

var_dump($object->title); // "Clone title"

var_dump($object->inner === $clone->inner); // true, the same instance

1

Trái ngược với niềm tin phổ biến, một biến

$object = new class {

public \stdClass $inner;

 

public function __construct()

{

$this->inner = (object) [];

}

 

public function __clone()

{

$this->inner = clone $this->inner;

}

};

 

$clone = clone $object;

 

var_dump($object->inner == $clone->inner); // true, equivalent

var_dump($object->inner === $clone->inner); // false, not the same instance

5 không riêng tư đối với cá thể mà là riêng cho lớp của cá thể đó 🤯. Vì vậy, trong ngữ cảnh của cùng một lớp, bạn có thể tham chiếu và cập nhật bất kỳ biến riêng tư nào trên một thể hiện như vậy

Như bạn có thể thấy điều này rất hữu ích để tạo một bản sao, đồng thời cập nhật một số giá trị của nó trong cùng một cuộc gọi

Cảm ơn vì đã đọc

Tôi hy vọng bạn thích đọc bài viết này. Nếu vậy, vui lòng để lại phản ứng 👍 hoặc nhận xét 💬 và cân nhắc đăng ký nhận bản tin của tôi. Tôi viết bài về PHP hầu như mỗi tuần. Bạn cũng có thể theo dõi tôi trên twitter để biết thêm nội dung và mẹo không thường xuyên

Bản sao nông trong PHP là gì?

Bản sao nông sao chép càng ít bản sao càng tốt . Bản sao nông sao chép tất cả các giá trị và tham chiếu vào một phiên bản mới. Trong Bản sao nông, bất kỳ thay đổi nào của thành viên tham chiếu đều ảnh hưởng đến cả hai phương thức.

Bản sao nông và sâu là gì, hãy giải thích từng ví dụ?

Trong Bản sao nông, một bản sao của đối tượng ban đầu được lưu trữ và cuối cùng chỉ có địa chỉ tham chiếu được sao chép. Trong Bản sao sâu, cả bản sao của đối tượng gốc và bản sao lặp lại đều được lưu trữ .

Bản sao nông có nghĩa là gì?

Bản sao nông của đối tượng là bản sao có thuộc tính chia sẻ cùng tham chiếu (trỏ đến cùng giá trị cơ bản) như thuộc tính của đối tượng nguồn mà từ đó bản sao được tạo ra< . .

Bản sao nông trong OOP là gì?

Bản sao nông là một đối tượng được tạo từ một đối tượng hiện có bằng cách sao chép tất cả các giá trị kiểu nguyên thủy và tham chiếu bản sao của tất cả các loại đối tượng tham chiếu được liên kết. That simply means, if your object has all primitive data types, then all the value will be copied.