Đô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âuGhi chú. Bạn có nhận thấy chúng tôi đã tham chiếu
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?
$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
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
0Như 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
8nhà 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
3Trong 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 instance
1
$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
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
1Trá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ậyNhư 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