Trong php, các đối tượng được truyền theo giá trị hoặc theo tham chiếu

các biến nguyên thủy php được truyền theo giá trị cho một hàm. Các đối tượng cũng được truyền theo giá trị nhưng điểm khác biệt là giá trị tham chiếu của đối tượng được truyền cho một hàm. Việc thêm dấu và vào tham số sẽ làm cho tham số được truyền bởi các tham chiếu cho dù tham số đó là biến nguyên thủy hay biến đối tượng

định nghĩa mô hình đối tượng chính thức của php

Trong PHP 5 có một Mô hình đối tượng mới. Việc xử lý các đối tượng của PHP đã được viết lại hoàn toàn, cho phép hiệu suất tốt hơn và nhiều tính năng hơn. Trong các phiên bản trước của PHP, các đối tượng được xử lý như các kiểu nguyên thủy (ví dụ: số nguyên và chuỗi). Hạn chế của phương thức này là về mặt ngữ nghĩa, toàn bộ đối tượng đã được sao chép khi một biến được gán hoặc được truyền dưới dạng tham số cho một phương thức. Theo cách tiếp cận mới, các đối tượng được tham chiếu theo tay cầm chứ không phải theo giá trị (người ta có thể coi tay cầm là định danh của đối tượng)

Theo mặc định, các biến PHP, nhưng không phải đối tượng, được truyền theo giá trị. Khi các biến PHP được truyền theo giá trị, phạm vi biến, được xác định ở cấp hàm được liên kết trong phạm vi của hàm. Việc sửa đổi một trong hai biến không có tác động

Hãy xem một ví dụ

Đầu ra sẽ như sau

  Function w3docs
  Global w3docs

Để truyền biến theo tham chiếu, cần thêm ký hiệu dấu và (&) trước đối số của biến

Một ví dụ về một chức năng như vậy sẽ như sau. hàm( &$x )

Phạm vi của các biến toàn cục và hàm trở thành toàn cầu. Lý do là chúng được xác định bởi cùng một tham chiếu. Do đó, sau khi thay đổi biến toàn cục, biến bên trong hàm cũng bị thay đổi theo.

Đây là một ví dụ rõ ràng

đầu ra sẽ là

  Function w3docs 
  Function w3docs
Các đối tượng PHP theo mặc định đang được truyền theo tham chiếu

Đầu ra sẽ như sau

1

Theo quy định, các biến PHP bắt đầu bằng dấu $ theo sau là tên biến

Khi gán một giá trị văn bản cho một biến, việc đặt dấu ngoặc kép xung quanh giá trị là cần thiết

Khác với các ngôn ngữ lập trình khác, PHP không có lệnh khai báo biến. Nó được tạo ra tại thời điểm một giá trị được gán cho nó lần đầu tiên

Trong PHP, biến là nơi chứa dữ liệu

Các biến PHP có thể có cả tên ngắn (ví dụ: x và y) và tên mô tả hơn (tên trái cây, tuổi, chiều cao, v.v.)

Trong bài viết này, tôi sẽ nói về cách các tham chiếu đối tượng và biến được kiểm soát trong bộ nhớ, vì đây là một vấn đề có thể tạo ra các cuộc thảo luận và ý kiến ​​khác nhau. Một câu hỏi để suy ngẫm là. “Theo mặc định, các đối tượng được truyền bằng tham chiếu hoặc bằng bản sao trong PHP?”

Qua

Agustin Villalba

Augustin là một kỹ sư PHP full-stack được Zend chứng nhận với hơn 10 năm kinh nghiệm tại các tổ chức như FIFA và Phòng thí nghiệm Sinh học Phân tử Châu Âu

ĐĂNG LẠI

ĐĂNG LẠI

Lần đầu tiên tôi soạn thảo bài viết này khi đang học để lấy chứng chỉ PHP nhằm nỗ lực hiểu rõ hơn cách PHP quản lý các biến và đối tượng trong bộ nhớ. Sau khi nghiên cứu rất nhiều, tôi nhận ra rằng không dễ để tìm ra câu trả lời cho câu hỏi của mình, vì vậy sau khi hoàn thành, tôi quyết định ghi lại thông tin để mọi người có thể tìm thấy tất cả ở một nơi

Trong bài viết này, tôi sẽ nói về cách các tham chiếu đối tượng và biến được kiểm soát trong bộ nhớ, vì đây là một vấn đề có thể tạo ra các cuộc thảo luận và ý kiến ​​khác nhau. Một câu hỏi để suy ngẫm là. “Theo mặc định, các đối tượng được truyền bằng tham chiếu hoặc bằng bản sao trong PHP?”

PHP tạo các đối tượng trong bộ nhớ như thế nào khi thực hiện một câu lệnh như

1
2? . Tuy nhiên, điều quan trọng đối với các nhà phát triển PHP giỏi là phải biết và hiểu cách các biến và đối tượng được quản lý nội bộ trong quá trình thực thi ứng dụng của họ.

Objects and references in PHP memory and PHP garbage collection

Đối tượng và tham chiếu trong PHP

Nhiều người nói—trong sách PHP và trên mạng—rằng các đối tượng trong PHP được chuyển theo tham chiếu theo mặc định. Những người khác nói rằng các đối tượng trong PHP được phân bổ theo bản sao. Để tìm ra câu nào đúng, trước tiên chúng ta phải phân tích cái gì là (và cái gì không) là tham chiếu trong PHP

Điều gì không phải là tài liệu tham khảo trong PHP?

Quan trọng hơn việc biết những tham chiếu nào trong PHP là biết chúng không phải là gì. Trong PHP, tham chiếu không phải là con trỏ kiểu C; . Tại sao? . Nhưng sau đó, tài liệu tham khảo là gì?

Tài liệu tham khảo trong PHP là gì?

Trong PHP, tham chiếu là “bí danh” cho phép hai biến khác nhau đọc và ghi một giá trị. Nói cách khác, chúng là các cơ chế cho phép truy cập vào cùng một giá trị từ các biến có tên khác nhau để chúng hoạt động như thể chúng là cùng một biến. Hãy nhớ rằng trong PHP, tên biến và nội dung của biến là hai thứ hoàn toàn khác nhau, được liên kết với nhau trong cái được gọi là “bảng ký hiệu”. ” Vì vậy, khi chúng ta tạo một tham chiếu, nó chỉ cần thêm một bí danh cho biến đó trong bảng ký hiệu. Giả sử chúng ta có đoạn mã sau

$a = new Foo();

Khi câu lệnh trên được thực thi, biến

1
3 được tạo trong bộ nhớ, một đối tượng kiểu
1
4 được tạo trong bộ nhớ và một mục nhập được thêm vào bảng ký hiệu chỉ ra rằng biến
1
3 “tham chiếu” (hoặc có liên quan đến, hoặc . Về mặt khái niệm, chúng tôi có một cái gì đó giống như hình minh họa này

Object references in PHP memory

Bài kiểm tra nhỏ bất ngờ. Điều gì xảy ra nếu chúng ta thực hiện điều này?

$b = $a;

Không phải là

$b = $a;
2 trở thành một tài liệu tham khảo của
1
3; . Điều thực sự xảy ra là chúng ta đã tạo một biến mới
$b = $a;
2 trong bộ nhớ và sau đó thêm một mục mới vào bảng ký hiệu chỉ ra rằng biến
$b = $a;
2 cũng tham chiếu đến cùng một đối tượng
1
4 mà
1
3 không. Vì vậy, trực quan, chúng tôi có một cái gì đó tương tự như những gì nó được hiển thị trong hình minh họa này

Object references in PHP memory

Bây giờ, nếu chúng ta thực hiện

$c = &$a;

Chúng tôi sẽ tạo một biến thứ ba

$c = &$a;
0 trong bộ nhớ, nhưng không phải là một mục mới trong bảng ký hiệu cho
$c = &$a;
0. Thay vào đó, trong bảng ký hiệu, người ta ghi rằng
$c = &$a;
0 là bí danh của
1
3, vì vậy nó sẽ hoạt động giống hệt nhau, nhưng
$c = &$a;
0 không phải là con trỏ tới
1
3—không giống như trong C, cái này tạo ra thứ gọi là con trỏ tới con trỏ. Để hình dung, chúng ta có một cái gì đó tương tự như trong hình minh họa này

Diagram of variables and their aliases

Ngay khi chúng tôi muốn sửa đổi giá trị của bất kỳ biến nào trong ba biến này (i. e. , viết một giá trị mới), PHP sẽ phải tạo một cấu trúc

$c = &$a;
6 mới trong bộ nhớ để tách nội dung của biến
$b = $a;
2 và cặp
1
3/
$c = &$a;
0 để chúng có thể được sửa đổi một cách độc lập mà không ảnh hưởng đến giá trị của biến kia. Vì vậy, nếu chúng ta thêm dòng sau vào tập lệnh trước

  Function w3docs 
  Function w3docs
7

Trong bộ nhớ, chúng ta sẽ có một tình huống như minh họa trong hình sau

Graphic representation of the situation described above

Bây giờ, hãy xem xét một ví dụ đầy đủ hơn

  Function w3docs 
  Function w3docs
8

Đầu ra được tạo bởi việc triển khai tập lệnh trên là

  Function w3docs 
  Function w3docs
9

Bộ sưu tập rác PHP

Cuối cùng, hãy xem cách bộ sưu tập rác PHP hoạt động, vì nó đã được giới thiệu trong phiên bản 5. 3. Một đối tượng hoặc biến trong bộ nhớ PHP sẽ bị bộ thu gom rác PHP xóa khi không có tham chiếu đến đối tượng đó trong bảng ký hiệu. Tức là, PHP duy trì một bộ đếm tham chiếu của một đối tượng ngay từ khi nó được tạo để trong quá trình thực thi tập lệnh PHP, bộ đếm sẽ tăng và giảm bộ đếm tham chiếu đó dựa trên các biến đang “trỏ” tới nó. Khi số lượng tham chiếu đạt đến 0 (i. e. , không có gì tham chiếu đến đối tượng đó và do đó, nó không được sử dụng), PHP đánh dấu đối tượng đó là có thể tháo rời, để trong lần tiếp theo của trình thu gom rác PHP, nó sẽ bị xóa khỏi bộ nhớ, giải phóng không gian đó để sử dụng lại. Nếu bạn muốn biết thêm chi tiết chuyên sâu về cách hoạt động của bộ sưu tập rác PHP, hãy đọc tài liệu này

Bớt tư tưởng

Tôi hy vọng tôi đã làm rõ một chút cách PHP xử lý các đối tượng và biến trong bộ nhớ và cách nó “chọn” các đối tượng cần được loại bỏ bởi trình thu gom rác PHP

Bây giờ bạn đã hiểu cách PHP quản lý các biến và đối tượng trong bộ nhớ bên trong, hãy lấy máy tính xách tay của bạn và bắt đầu thử nghiệm một số mã để chứng minh những gì bạn đã học. Hãy thử chơi xung quanh với các biến và tham chiếu. Ngoài ra, hãy thử nghiệm xem việc thay đổi giá trị của một biến có thể ảnh hưởng như thế nào đến giá trị của biến khác tham chiếu đến nó. Đây là một câu hỏi dành cho bạn. Giá trị của

1
3 và
$b = $a;
2 sau khi đoạn mã dưới đây được thực thi là bao nhiêu?

1
1

Nếu bạn muốn đọc thêm về các tính năng hiệu suất của PHP, hãy xem bài đăng này của đồng nghiệp Toptaler Vilson Duka

Hiểu những điều cơ bản

Tài liệu tham khảo trong PHP là gì?

Trong PHP, tham chiếu là “bí danh” cho phép hai biến khác nhau đọc và ghi một giá trị

Bộ sưu tập rác PHP hoạt động như thế nào?

PHP duy trì số lượng tham chiếu tới một đối tượng từ thời điểm nó được tạo. Khi không có tham chiếu đến đối tượng đó trong bảng ký hiệu, trình thu gom rác PHP sẽ loại bỏ nó

Các tham chiếu bộ nhớ PHP được lưu trữ như thế nào?

Các tham chiếu bộ nhớ PHP được lưu trữ trong kho lưu trữ khóa-giá trị được gọi là bảng ký hiệu

Thẻ

PHPGarbageCollectionMemoryReferences

Người làm việc tự do? Tìm công việc tiếp theo của bạn.

Việc làm Lập trình viên PHP

Xem thông tin đầy đủ

Agustin Villalba

Nhà phát triển PHP tự do

Thông tin về các Tác giả

Agustin là một nhà phát triển web với 12 năm kinh nghiệm phát triển các ứng dụng web full-stack. Ông đi đầu trong việc phát triển một dự án web cho Ban trọng tài FIFA và phát triển cho Phòng thí nghiệm sinh học phân tử châu Âu (www. huy hiệu. de). Anh ấy cũng là một Zend PHP 5. 3 Kỹ sư được chứng nhận

Thuê Agustin

Bình luận

Usama Ahmed

Tôi mất chưa đầy 3 giây để tìm hiểu cách php quản lý các đối tượng. Hướng dẫn chính thức của PHP có rất nhiều tài liệu về nó. Toptal có buộc bạn phải xây dựng bài viết từ tìm kiếm trên google không?

Usama Ahmed

Tôi mất chưa đầy 3 giây để tìm hiểu cách php quản lý các đối tượng. Hướng dẫn chính thức của PHP có rất nhiều tài liệu về nó. Toptal có buộc bạn phải xây dựng bài viết từ tìm kiếm trên google không?

Zbynek

con trỏ và tham chiếu trong c không giống nhau, int a = 1; . trong php không có con trỏ, nhưng có các tham chiếu như trong c và chúng hoạt động chủ yếu giống như trong c, vì vậy bạn không nên so sánh con trỏ c với tham chiếu php, điều đó không có ý nghĩa

Zbynek

con trỏ và tham chiếu trong c không giống nhau, int a = 1; . trong php không có con trỏ, nhưng có các tham chiếu như trong c và chúng hoạt động chủ yếu giống như trong c, vì vậy bạn không nên so sánh con trỏ c với tham chiếu php, điều đó không có ý nghĩa

Agustín

Xin chào Zbynek, Cảm ơn bạn đã bình luận. Chính xác thì con trỏ và tham chiếu không giống nhau, đó là những gì chúng tôi nêu trong bài viết. Ngoài ra, như bạn đã đề cập, chúng tôi giải thích rằng không giống như con trỏ C, các tham chiếu PHP không phải là địa chỉ bộ nhớ, vì vậy phép so sánh được sử dụng để nhận xét rằng chúng không giống nhau;)

Agustín

Xin chào Zbynek, Cảm ơn bạn đã bình luận. Chính xác thì con trỏ và tham chiếu không giống nhau, đó là những gì chúng tôi nêu trong bài viết. Ngoài ra, như bạn đã đề cập, chúng tôi giải thích rằng không giống như con trỏ C, các tham chiếu PHP không phải là địa chỉ bộ nhớ, vì vậy phép so sánh được sử dụng để nhận xét rằng chúng không giống nhau;)

Zbynek

bạn đang nghĩ vậy thì có ai đó nghĩ tham chiếu php là con trỏ C không?

Zbynek

bạn đang nghĩ vậy thì có ai đó nghĩ tham chiếu php là con trỏ C không?

Agustín

Tôi thực sự nghi ngờ rằng bạn có thể tìm thấy thông tin chi tiết và được giải thích rõ ràng về nội bộ PHP trong 3 giây. Mặc dù tài liệu PHP thường tốt, nhưng điều đó không có nghĩa là mọi người đều có "chuyên môn" của bạn để hiểu nó. Bài đăng này được thực hiện dựa trên nghiên cứu và tài liệu riêng, vì vậy nếu bạn không thích nó thì cũng tốt thôi (tất nhiên rồi. ), nhưng bình luận của bạn không thêm bất kỳ thảo luận hoặc tranh luận nào về chủ đề này, vì vậy không có nhiều điều để trả lời. ;)

Agustín

Tôi thực sự nghi ngờ rằng bạn có thể tìm thấy thông tin chi tiết và được giải thích rõ ràng về nội bộ PHP trong 3 giây. Mặc dù tài liệu PHP thường tốt, nhưng điều đó không có nghĩa là mọi người đều có "chuyên môn" của bạn để hiểu nó. Bài đăng này được thực hiện dựa trên nghiên cứu và tài liệu riêng, vì vậy nếu bạn không thích nó thì cũng tốt thôi (tất nhiên rồi. ), nhưng bình luận của bạn không thêm bất kỳ thảo luận hoặc tranh luận nào về chủ đề này, vì vậy không có nhiều điều để trả lời. ;)

Lars Moelleken

Heyho, đây là một nhận xét mang tính xây dựng hơn một chút ;-) Nếu bạn chạy tập lệnh php sau, bạn có thể chỉ cần xem các tham chiếu và sao chép khi ghi đang hoạt động như thế nào. bắt đầu. mảng 88 byte. 8524592 byte chức năng1-bắt đầu. 8524608 byte chức năng1-end. 17049016 byte mảng-test4. 8524536 byte chức năng2-bắt đầu. 8524552 byte chức năng2-end. 8524616 byte mảng-test4_ref. 8524552 byte kết thúc. 8524552 byte https. //github. com/voku/php_zval_test/blob/master/test4. php

Lars Moelleken

Heyho, đây là một nhận xét mang tính xây dựng hơn một chút ;-) Nếu bạn chạy tập lệnh php sau, bạn có thể chỉ cần xem các tham chiếu và sao chép khi ghi đang hoạt động như thế nào. bắt đầu. mảng 88 byte. 8524592 byte chức năng1-bắt đầu. 8524608 byte chức năng1-end. 17049016 byte mảng-test4. 8524536 byte chức năng2-bắt đầu. 8524552 byte chức năng2-end. 8524616 byte mảng-test4_ref. 8524552 byte kết thúc. 8524552 byte https. //github. com/voku/php_zval_test/blob/master/test4. php

Mladen Janjetovic

Điều này hoàn toàn không đúng, tôi đã cố gắng tìm một thứ được giải thích rõ ràng như thế này và tôi đã mất một lúc

Mladen Janjetovic

Điều này hoàn toàn không đúng, tôi đã cố gắng tìm một thứ được giải thích rõ ràng như thế này và tôi đã mất một lúc

Neda Abbasi

Cách gán bộ nhớ cho các biến trong php?

Neda Abbasi

Cách gán bộ nhớ cho các biến trong php?

OAH

đừng có ghét như vậy. Viết cái gì tầm cỡ này nọ rồi “khoe”. Cảm ơn các bác trong toptal vì bài viết rất hay này. Giữ công việc tốt Agustin

OAH

Bây giờ đó là một số thứ nghiêm trọng ở đây. Kết hợp điều này với bài đăng tuyệt vời từ stackoverflow trên mảng php "sao chép khi ghi" làm cho bộ nhớ mgmt trong php trở nên dễ nắm bắt hơn rất nhiều. Cảm ơn mọi người

Các đối tượng có được truyền qua tham chiếu không?

Tham chiếu đối tượng được truyền theo giá trị . Do đó, mặc dù Java truyền tham số cho phương thức theo giá trị, nhưng nếu biến trỏ đến tham chiếu đối tượng thì đối tượng thực cũng sẽ bị thay đổi.

Bạn có nên chuyển qua tham chiếu trong PHP không?

Câu trả lời ngắn gọn là sử dụng tài liệu tham khảo khi bạn cần chức năng mà họ cung cấp . Đừng nghĩ về chúng về mặt sử dụng bộ nhớ hoặc tốc độ. Truyền theo tham chiếu sẽ luôn chậm hơn nếu biến chỉ được đọc. Mọi thứ được truyền theo giá trị, bao gồm cả các đối tượng.

Các biến PHP có tham chiếu không?

Các biến PHP được gán theo giá trị, được truyền cho các hàm theo giá trị và khi chứa/đại diện cho các đối tượng được truyền theo tham chiếu . Bạn có thể buộc các biến chuyển qua tham chiếu bằng cách sử dụng '&'.

Các mảng PHP có được chuyển qua tham chiếu 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.