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?” Show
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 CHIA SẺ CHIA SẺ 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ư Đối tượng và tham chiếu trong PHPNhiề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
Khi câu lệnh trên được thực thi, biến 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?
Không phải là 2 trở thành tham chiếu của $a ; . Điều thực sự xảy ra là chúng ta đã tạo một biến mới 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 2 cũng tham chiếu đến cùng một đối tượng Foo mà $a 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àyBây giờ, nếu chúng ta thực hiện
Chúng tôi sẽ tạo một biến thứ ba 0 trong bộ nhớ, nhưng không phải là một mục mới trong bảng ký hiệu cho 0. Thay vào đó, trong bảng ký hiệu, nó được ghi lại rằng 0 là bí danh của $a , vì vậy nó sẽ hoạt động giống hệt nhau, nhưng 0 không phải là con trỏ tới $a —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àyNgay 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 6 mới trong bộ nhớ để tách nội dung của biến 2 và cặp $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
Trong bộ nhớ, chúng ta sẽ có một tình huống như minh họa trong hình sau Bây giờ, hãy xem xét một ví dụ đầy đủ hơn
Đầu ra được tạo bởi việc triển khai tập lệnh trên là
Bộ sưu tập rác PHPCuố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ưởngTô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 2 sau khi mã bên dưới được thực thi là gì?
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ảnTà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ẻ PHPGarbageCollectionMemoryReferencesNgườ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ậnUsama 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 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 Làm cách nào để cung cấp tài liệu tham khảo trong PHP?Trong PHP, tên biến và nội dung biến khác nhau nên cùng một nội dung có thể có tên khác nhau. Biến tham chiếu được tạo bằng cách tiền tố & ký hiệu cho biến ban đầu . Do đó b=&a sẽ có nghĩa là bisareferewncevariableofa.
Khi nào sử dụng tham chiếu trong PHP?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.
Bạn có nên chuyển qua tham chiếu trong PHP không?Vì vậy, hãy sử dụng tham chiếu chuyển tiếp bất cứ khi nào bạn muốn một hàm thay đổi một biến được truyền cho nó . Đơn giản. Nhân tiện, đừng cố gắng đặt dấu và trước tên đối số trong lời gọi hàm của bạn. tạm biệt( &$myVar ); .
Làm cách nào để chuyển mảng theo tham chiếu trong PHP?Đây là một tập lệnh PHP về cách chuyển mảng làm tham chiếu. |