Các đối tượng trong PHP được gán theo tham chiếu, vì vậy việc sao chép một đối tượng bằng toán tử = sẽ dẫn đến một biến thứ hai tham chiếu đến cùng một đối tượng chứ không phải là một bản sao thực sự. Nhập chức năng sao chép của PHP để tạo một bản sao nông của đối tượng
Sử dụng = để sao chép một đối tượng chỉ sao chép tham chiếu
Để minh họa cách PHP chỉ tạo tham chiếu đến đối tượng ban đầu bằng toán tử =, hãy xem ví dụ sau. [Lưu ý rằng tôi đã gán = màu đỏ trong ví dụ]
class foo {
public $bar;
}
$foo = new foo[];
$foo->bar = 'baz';
$foo2 = $foo;
$foo2->bar = 'bat';
echo $foo->bar;
echo $foo2->bar;
Cả hai dòng echo ở cuối ví dụ sẽ lặp lại "bat" chứ không phải "baz" và "bat", bởi vì $foo2 là tham chiếu đến $foo và việc truy cập các thuộc tính cũng như gọi phương thức cho $foo2 thực sự là tham chiếu đến các thuộc tính và phương thức đó
Sử dụng bản sao để sao chép và đối tượng sao chép đối tượng
Sử dụng cùng một ví dụ, nhưng sử dụng bản sao thay vì sao chép đối tượng sẽ dẫn đến một bản sao của đối tượng ban đầu. Việc thay đổi thuộc tính và phương thức gọi sẽ làm như vậy đối với đối tượng được sao chép chứ không phải đối tượng gốc
Sự khác biệt duy nhất giữa ví dụ trên và ví dụ này là "=" trở thành "bản sao" được đánh dấu màu đỏ trong cả hai ví dụ
class foo {
public $bar;
}
$foo = new foo[];
$foo->bar = 'baz';
$foo2 = clone $foo;
$foo2->bar = 'bat';
echo $foo->bar . "n";
echo $foo2->bar . "n";
Ví dụ thứ hai xuất ra "baz" và sau đó là "bat"
Bản sao nông
Nhân bản một đối tượng tạo ra một bản sao "nông" của đối tượng ban đầu. Điều này có nghĩa là bất kỳ thuộc tính nào là tham chiếu đến các biến khác sẽ vẫn là tham chiếu đến các biến đó và không sao chép chính chúng
Phương thức __clone
Nếu đối tượng chứa phương thức __clone thì nó sẽ được gọi khi đối tượng được sao chép. Nó phải là một chức năng có thể truy cập công khai và không thể được gọi trực tiếp nếu không PHP sẽ kết thúc với một lỗi nghiêm trọng. Bạn sẽ không thực sự lặp lại đầu ra khi sao chép, nhưng nếu đối tượng được sao chép trong ví dụ bên dưới, nó sẽ lặp lại "tôi đã được sao chép"
sao chép và sao chép về cơ bản làm điều tương tự và sẽ tạo một bản sao của các tham chiếu đến một đối tượng. Sự khác biệt đến ở chỗ bạn có thể ngắt tham chiếu trong một bản sao NẾU bạn xử lý nó trong đối tượng mà bạn sao chép - nó không xảy ra một cách tự động giống như trong các ngôn ngữ khác như C# và python
Nhanh chóng và hèn hạ
Nhưng nếu bạn xử lý hành động nhân bản, kết quả sẽ thay đổi
Câu trả lời ngắn gọn là nó phụ thuộc vào những gì bạn đang sao chép. Nếu giá trị là một đối tượng thì việc gán giá trị cho một biến khác sẽ chỉ sao chép một tham chiếu. Trong tất cả các trường hợp khác [số, chuỗi, mảng], nó sẽ tạo một bản sao
ví dụ
$a = 1;
$b = $a;
$b = 2;
var_dump[$a,$b];
đầu ra
int[1]
int[2]
$a = array[];
$a['val'] = 1;
$b = $a;
$b['val'] = 2;
var_dump[$a,$b];
đầu ra
array[1] {
["val"]=>
int[1]
}
array[1] {
["val"]=>
int[2]
}
Vì vậy, trong cả hai trường hợp này, biến $b là thứ riêng của nó và bạn có thể thay đổi nó mà không ảnh hưởng đến $a
Nhưng với một đối tượng
________số 8đầu ra
object[stdClass]#718 [1] {
["val"]=>
int[2]
}
object[stdClass]#718 [1] {
["val"]=>
int[2]
}
Cả hai biến hiện có cùng giá trị, vì $b chỉ là một tham chiếu đến $a. Ngoài ra, việc thay đổi $a sẽ ảnh hưởng đến $b
Sự khác biệt chính giữa bản sao và chế độ xem của một mảng là bản sao là một mảng mới và chế độ xem chỉ là chế độ xem của mảng ban đầu
Bản sao sở hữu dữ liệu và mọi thay đổi đối với bản sao sẽ không ảnh hưởng đến mảng ban đầu và mọi thay đổi đối với mảng ban đầu sẽ không ảnh hưởng đến bản sao
Chế độ xem không sở hữu dữ liệu và mọi thay đổi được thực hiện đối với chế độ xem sẽ ảnh hưởng đến mảng ban đầu và mọi thay đổi được thực hiện đối với mảng ban đầu sẽ ảnh hưởng đến chế độ xem
SAO CHÉP
Thí dụ
Tạo một bản sao, thay đổi mảng ban đầu và hiển thị cả hai mảng
nhập numpy dưới dạng np
arr = np. mảng[[1, 2, 3, 4, 5]]
x = mảng. copy[]
arr[0] = 42
in[mảng]
in[x]
Bản sao KHÔNG NÊN bị ảnh hưởng bởi những thay đổi được thực hiện đối với mảng ban đầu
LƯỢT XEM
Thí dụ
Tạo dạng xem, thay đổi mảng ban đầu và hiển thị cả hai mảng
nhập numpy dưới dạng np
arr = np. mảng[[1, 2, 3, 4, 5]]
x = mảng. view[]
arr[0] = 42
in[mảng]
in[x]
Chế độ xem NÊN bị ảnh hưởng bởi những thay đổi được thực hiện đối với mảng ban đầu
Thực hiện thay đổi trong VIEW
Thí dụ
Tạo chế độ xem, thay đổi chế độ xem và hiển thị cả hai mảng
nhập numpy dưới dạng np
arr = np. mảng[[1, 2, 3, 4, 5]]
x = mảng. lượt xem[]
x[0] = 31
in[mảng]
in[x]
Mảng ban đầu NÊN bị ảnh hưởng bởi những thay đổi được thực hiện đối với dạng xem
Kiểm tra xem Array có sở hữu dữ liệu của nó không
Như đã đề cập ở trên, bản sao sở hữu dữ liệu và chế độ xem không sở hữu dữ liệu, nhưng làm cách nào để kiểm tra điều này?