Tại sao các tài liệu tham khảo hiếm khi được sử dụng trong PHP?


26

Tôi có một số kiến ​​thức về C ++ và biết rằng các con trỏ thường được sử dụng ở đó, nhưng tôi đã bắt đầu xem xét mã nguồn mở PHP và tôi không bao giờ thấy mã sử dụng các tham chiếu trong các phương thức.

Thay vào đó, mã luôn sử dụng giá trị trả về thay vì chuyển tham chiếu đến biến cho phương thức, sau đó thay đổi giá trị của biến đó và chỉ trả về nó.

Tôi đã đọc được rằng sử dụng tài liệu tham khảo sử dụng ít bộ nhớ hơn, vậy tại sao chúng không được sử dụng trong PHP?


19
Sử dụng tham số pass-by-Reference là "lập trình hiệu ứng phụ" - sử dụng hàm để trả về một giá trị sẽ rõ ràng hơn đáng kể khi đọc mã. Điều đó nói rằng, khá nhiều chức năng cốt lõi của PHP sử dụng tài liệu tham khảo.
halfer

3
PHP vượt qua các đối tượng theo tham chiếu theo mặc định.

2
sắp xếp mảng là một ví dụ điển hình của các hàm PHP cốt lõi được truyền qua tham chiếu
Mark Baker

2
Các tài liệu tham khảo PHP không phải là con trỏ và thường là một vấn đề khó khăn nếu bạn không hoàn toàn mong đợi chúng xuất hiện ở đâu.
lanzz

2
Nếu bạn cần nhiều tiền return array($foo, $bar);list($A, $B) = foobar();
lãi

Câu trả lời:


49

Khẳng định của bạn rằng các tài liệu tham khảo hiếm khi được sử dụng là không chính xác. Như những người khác đã đề cập, có rất nhiều hàm gốc sử dụng các tham chiếu, các ví dụ đáng chú ý bao gồm các hàm sắp xếp mảngpreg_match()/ preg_match_all(). Nếu bạn đang sử dụng bất kỳ chức năng nào trong mã này, bạn cũng đang sử dụng tài liệu tham khảo.

Tiếp tục, các tài liệu tham khảo trong PHP không phải là con trỏ. Vì bạn đến từ nền C ++, tôi có thể hiểu được sự nhầm lẫn, nhưng các tham chiếu PHP là một con thú hoàn toàn khác, chúng là bí danh cho một bảng biểu tượng . Bất kỳ hiệu suất nào bạn có thể mong đợi từ các tham chiếu C ++ chỉ đơn giản là không áp dụng cho các tham chiếu PHP.

Trong thực tế, trong hầu hết các kịch bản chuyển qua giá trị nhanh hơn và ít bộ nhớ hơn so với chuyển qua tham chiếu. Công cụ Zend, lõi của PHP, sử dụng cơ chế tối ưu hóa sao chép khi ghi mà không tạo bản sao của biến cho đến khi nó được sửa đổi. Chuyển qua tham chiếu thường phá vỡ mô hình sao chép trên ghi và yêu cầu một bản sao cho dù bạn có sửa đổi giá trị hay không.

Đừng ngại sử dụng các tài liệu tham khảo trong PHP khi bạn cần, nhưng đừng chỉ làm điều đó như một nỗ lực để tối ưu hóa vi mô. Hãy nhớ rằng, tối ưu hóa sớm là gốc rễ của mọi tội lỗi .

Đọc thêm:


Cảm ơn đã sửa @NikiC. Câu trả lời lười biếng này ...
yannis

Để hoàn thành câu trả lời, thật tuyệt khi chỉ ra rằng tất cả các đối tượng được truyền bằng tham chiếu trong PHP.
Florian Margaine

@FlorianMargaine Điều đó không hoàn toàn chính xác (xem liên kết thứ hai trong phần đọc thêm).
yannis

2
@FlorianMargaine Không, hai người rất khác nhau và điều quan trọng là phải nhận ra lý do tại sao lại như vậy.
phant0m

3
@FlorianMargaine Không, giả sử các đối tượng được truyền bằng tham chiếu trong PHP: đã f($obj)cho function f($x) { $x = new X; }, sẽ $objtham chiếu đến một đối tượng khác so với trước khi gọi đến f(). Tuy nhiên, vì các đối tượng không được chuyển qua tham chiếu, $ obj không được sửa đổi nếu bạn thực hiện điều này với PHP. Theo cách đó, PHP làm tương tự như Java.
phant0m

8

PHP đã thực hiện một điều sao chép khi ghi mà nó không tạo ra giá trị mới cho đến khi bạn thay đổi thứ gì đó, do đó không có nhiều bộ nhớ được lưu bằng cách sử dụng các tham chiếu. Làm như vậy thậm chí có thể gây rối với một số thứ mà PHP thực hiện trong nội bộ để giảm mức sử dụng bộ nhớ, khiến mọi thứ trở nên tồi tệ hơn.

Thêm vào đó là thực tế rằng các tài liệu tham khảo làm cho mọi thứ nói chung hơi kỳ diệu. Mặc định, và do đó, hầu hết mọi người mong đợi, là giá trị truyền qua; Khi tôi chuyển $iđến một chức năng, nó làm phức tạp mọi thứ rất nhiều để quan tâm liệu chức năng đó có thay đổi $ihoàn toàn sang một thứ khác hoàn toàn không, và do đó tạo ra các bản sao phòng thủ chỉ trong trường hợp. (Nó có thể sửa đổi $inếu giá trị là một đối tượng, nhưng theo tôi thì không nên.)

Về cơ bản, tôi chỉ muốn tìm pass-by-tham khảo hữu ích cho "out" các thông số, có nghĩa là các biến i mong đợi để có được trở lại từ chức năng chứ không phải vượt qua trong, a la preg_match's &$matches. Ngay cả đối với các chức năng sửa đổi rõ ràng đối tượng được truyền vào, như sorthoặc array_pop, cảm thấy hơi khó chịu ... nhưng đó là những gì chúng ta đang mắc kẹt.


5

PHP là một ngôn ngữ định hướng web.
Các trang web được phục vụ nhanh và nên nhẹ.
Chương trình PHP thông thường sống một phần của giây và tiêu thụ vài trăm kilobyte bộ nhớ.
Không có sử dụng cho tối ưu hóa như vậy.


1
Điều này. Không cần con trỏ / tài liệu tham khảo, vì nó không gây rối ở mức độ thấp như C ++.
Kenneth Worden

8
Tại sao bài đăng này được 5+ ??? Nó không trả lời câu hỏi b) không đúng

1
Vì vậy, tài liệu tham khảo là chậm và tiêu thụ quá nhiều bộ nhớ?
Rocket Hazmat

1
@RocketHazmat Vâng, thật kỳ lạ, điều đó đúng.
yannis

3

Một số lý do trên bay:

  • PHP là ngôn ngữ kịch bản và không nhằm mục đích sử dụng làm phần mềm nhúng lõi (về cơ bản, bộ nhớ sẽ bị xóa ở cuối tập lệnh),
  • Vì PHP5, tham chiếu qua được ẩn cho các tham số đối tượng (vì vậy PHP sử dụng tham chiếu "ở phía sau").

1
Xem: php.net/manual/en/lingu.oop5.references.php cho điểm thứ hai của bạn.
yannis

2

Tôi nghĩ rằng đây chỉ là một sự lựa chọn của các nhà phát triển, không liên quan gì đến ngôn ngữ. Rất nhiều mã PHP (tích hợp và không) sử dụng tài liệu tham khảo. Hãy xem các hàm mảng trong PHP, rất nhiều trong số đó sử dụng các tài liệu tham khảo. preg_matchsử dụng tài liệu tham khảo.

Tôi nghĩ một trong những lý do khiến các nhà phát triển chọn không sử dụng tài liệu tham khảo là vì nó có thể gây nhầm lẫn. Bạn gọi một hàm và một trong các biến có thể (hoặc có thể không) được cập nhật vì đó là tham chiếu. Vì vậy, khi bạn gỡ lỗi, có thể không rõ lý do tại sao giá trị của $xjsut thay đổi một cách kỳ diệu.


1

Vấn đề cơ bản với câu hỏi của bạn là bạn cho rằng điều này cũng phổ biến trong C ++. Không phải vậy. Chúng tôi không thích các tham số đầu ra và sử dụng chúng ít nhất có thể - chúng chỉ thực sự phổ biến trong các API kiểu C.


0

Tôi biết nhiều hàm php làm như vậy. Có một cái nhìn vào preg_match()ví dụ. $matchessẽ được thông qua tham chiếu

Nếu bạn muốn viết một hàm cho chính mình lấy tham số bằng tham chiếu thì hãy sử dụng cú pháp sau

function byref(&$a, &$b, $c) {
    $a += $c;
    $b += $c;
    return $a * $b;
}

$ a và $ b được truyền bằng tham chiếu $ c được truyền theo giá trị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.