2011-01-12 36 views
11

Gán giá trị trả về mới theo tham chiếu là deprecated bằng PHP 5.3. Như vậy,PHP 5.3 và gán giá trị trả về mới bằng cách tham chiếu

$obj =& new Foo(); 

hiện ném một lỗi E_DEPRECATED.

Khi nâng cấp một ứng dụng lớn có nhiều mã cũ lên 5.3, điều này dẫn đến nhiều thông báo không mong muốn.

Để khắc phục sự cố này, tôi đang xem xét sử dụng cụm từ thông dụng để tìm và thay thế tất cả các phiên bản =& new bằng = new. Ví dụ, sau đây sẽ tìm thấy tất cả các file PHP, và quét sạch tất cả các trường của =& new:

find ./ -name '*.php' | xargs perl -p -i -e 's/=(\s*)&(\s*)?new\b/= new/g' 

Looking for câu trả lời cho các câu hỏi sau:

  1. nó sẽ chỉ làm việc tốt? Tôi có thể gặp phải những vấn đề tiềm ẩn nào?
  2. Nếu không, ví dụ về mã thay thế =& new bằng = new sẽ thay đổi hành vi trong PHP 5.3.
  3. Bất kỳ ví dụ nào về các thư viện phổ biến với điều này sẽ được biết là gây ra sự cố.
  4. Bạn có đề xuất những ý tưởng nào khác để giải quyết việc sửa số tiền lớn =& new?

Tôi nghi ngờ điều này sẽ hoạt động tốt, nhưng tìm kiếm các trường hợp cạnh mà tôi có thể gặp sự cố. Có, tôi biết tôi chỉ có thể thay đổi cài đặt báo cáo lỗi. Nhưng tôi không muốn giấu các thông báo, tôi muốn sửa chúng.

+0

E_DEPRECATED thuộc về lớp thông báo, không phải lỗi. Tôi không chắc bạn cần phải vội vàng sửa chữa nó (magic_quotes đã tuyên bố không được chấp nhận trong php 4.2 hoặc hơn). Đối với regex: bạn nên thêm một '\ b' sau' new', nhưng nếu không thì đó là phương pháp viết lại khả thi. Nhưng bạn chỉ có thể kiểm tra nếu nó làm suy yếu logic xử lý dự kiến ​​(mặc dù không chắc). – mario

+0

@mario E_DEPRECATED chỉ là lỗi * cấp *. Nó sẽ là thích hợp để đề cập đến nó một trong hai cách. Điểm tốt với \ b mặc dù. – mfonda

Trả lời

14

Cảm giác của bạn là đúng. Nó thường sẽ hoạt động tốt, nhưng có những trường hợp cạnh mà nó không.

Sử dụng =& có những khác biệt với =:

  • =& sẽ cố gắng làm cho phía bên phải tạo ra một tài liệu tham khảo; = sẽ không - ngay cả khi bên phải có thể mang lại một tham chiếu, như một hàm trả về bằng tham chiếu.
  • =& sẽ phá vỡ bộ tham chiếu cũ và đặt bên trái và bên phải cả hai trong một mới, trong khi = sẽ thay đổi giá trị của tất cả các phần tử trong cùng một tham chiếu được đặt làm bên trái với giá trị của phía bên phải .

Sự khác biệt đầu tiên và một nửa số thứ hai là không liên quan trong trường hợp này. Sau khi gán, sẽ chỉ có một biến với giá trị của đối tượng mới *, và các bộ tham chiếu phần tử đơn không có ý nghĩa gì. Tuy nhiên, thực tế là =& phá vỡ các tài liệu tham khảo trước thiết lập rất có ý nghĩa:

<?php 

$g = 4; 
$v =& $g; 
$v = new stdclass(); 
var_dump($g); // object(stdClass)#1 (0) { } 

$g = 4; 
$v =& $g; 
$v =& new stdclass(); 
var_dump($g); // int(4) 

* Trừ khi có lẽ các nhà xây dựng rò rỉ một tham chiếu, nhưng ngay cả khi nó bị rò rỉ, $this bên trong constructor có thể là một biến khác nhau, ngay cả khi nó trỏ cho cùng một đối tượng. Vì vậy, tôi nghi ngờ người ta có thể quan sát sự khác biệt hành vi do điều này.

+4

+1 để minh họa sự vỡ đoạn tài liệu tham khảo cũ. Nhưng lỗi chính tả, nó phải là '= &', không phải '& ='. – Jonah

+0

@Jonah Đã sửa, cảm ơn! – Artefacto

+0

Những thứ tuyệt vời. Không bao giờ nghĩ rằng nó tạo nên sự khác biệt. +1 – NikiC

3

Có, bạn sẽ chỉ có thể thay thế =& new bằng = new. Các đối tượng được truyền theo tham chiếu theo mặc định trong PHP 5.3, vì vậy không có hành vi nào sẽ thay đổi.

+1 để sửa thông báo thay vì ẩn thông báo.

+0

+1 (bắt buộc "tài liệu tham khảo được truyền theo giá trị, không phải đối tượng được chuyển bởi tham chiếu" pedantry đến đây.) – BoltClock

+0

+1 Tôi đang học nhanh. – Ish

+0

-1 Sai và không liên quan. Chúng không thể hoán đổi cho nhau và không ai vượt qua bất cứ điều gì (ngoại trừ các đối số hàm tạo) bằng cách tham chiếu hoặc theo giá trị ... – Artefacto

2

Không có vấn đề gì. Trong trường hợp xấu nhất này sẽ làm chậm ứng dụng của bạn trên PHP 4 một chút, nhưng nó chắc chắn sẽ không thay đổi chức năng.

Vấn đề duy nhất bạn có thể chạy về mặt lý thuyết là ai đó đã viết =& new trong một chuỗi. Tôi biết, điều này là rất không thể xảy ra, nhưng nếu bạn muốn thay thế thực sự chỉ tất cả các lần xuất hiện của '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW bạn nên làm như vậy bằng cách sử dụng Tokenizer.

+0

Chắc chắn, nhưng có lẽ đó có thể là một điều tốt. Nếu ai đó đã "sử dụng ví dụ" của một số mã trong nhận xét, thì regex sẽ khắc phục việc sử dụng ví dụ. Nhưng tôi cho rằng nó sẽ là xấu nếu nó là một ví dụ về những gì không làm :-) – mfonda

+0

Chúng không giống nhau. Điểm tốt với '= & new' xuất hiện trong một chuỗi mặc dù. – Artefacto

Các vấn đề liên quan