Sao chép mảng php mà không cần tham chiếu

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ạ

amount = &$value;

// Clone the object
$clone = clone $obj;
$copy = $obj;

// Change the value in the original object
$obj->amount = 6;

// The value for amount has changed in both...
print_r($clone);
print_r($copy);
// Output
//  MyClass Object ( [amount] => 6 ) MyClass Object ( [amount] => 6 )
?>

Nhưng nếu bạn xử lý hành động nhân bản, kết quả sẽ thay đổi

amount;
    unset($this->amount); // Unset breaks references
    $this->amount = $value;
  }
}

// Create an object with a reference
$value = 5;
$obj = new MyClass();
$obj->amount = &$value;

// Clone the object
$clone = clone $obj;
$copy = $obj;

// Change the value in the original object
$obj->amount = 6;

// The value is changed in copy but not in clone
print_r($copy);
print_r($clone);

// Output
// MyClass Object ( [amount] => 6 ) MyClass Object ( [amount] => 5 )
?>

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)

Tự mình thử »

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)

Tự mình thử »

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)

Tự mình thử »

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?

Làm cách nào để sao chép mảng trong PHP?

Hàm getArrayCopy() của lớp ArrayObject trong PHP được sử dụng để tạo một bản sao của ArrayObject này . Hàm này trả về bản sao của mảng có trong ArrayObject này.

Mảng PHP có được truyền theo tham chiếu hoặc giá trị không?

Đối với câu hỏi đầu tiên của bạn, mảng được truyền theo tham chiếu TRỪ KHI nó được sửa đổi trong phương thức/hàm bạn đang gọi . Nếu bạn cố gắng sửa đổi mảng trong phương thức/hàm, một bản sao của nó sẽ được tạo trước và sau đó chỉ bản sao được sửa đổi.

Chúng ta có thể chuyển mảng làm đối số trong PHP không?

Bạn có thể truyền một mảng làm đối số . Nó được sao chép theo giá trị (hoặc COW'd, về cơ bản có nghĩa giống với bạn), vì vậy bạn có thể array_pop() (và tương tự) tất cả những gì bạn thích trên đó và sẽ không ảnh hưởng đến bất kỳ thứ gì bên ngoài. hàm sendemail($id, $userid){ //. }

Làm cách nào tôi có thể nối một mảng vào một mảng khác trong PHP?

Sử dụng hàm array_push() , cái thứ hai sẽ được hợp nhất với cái thứ nhất. Trong hàm này, mảng thứ hai sẽ được thêm vào vị trí tiếp theo của mảng đầu tiên. Mảng hoàn chỉnh sẽ được đặt ở vị trí tiếp theo. $array1 = mảng(1, 2, 3, 4);