2010-12-14 18 views
7

Bạn có thể sử dụng @ khi trích xuất một giá trị có thể bị thiếu trong một mảng PHP không? Ví dụ:

$value = @$array['possibly_missing_key']; 

Các hành vi dự định:

if (isset($array['possibly_missing_key'])) { 
    $value = $array['possibly_missing_key']; 
} else { 
    $value = null; 
} 

Tôi muốn biết, trước khi lan rộng mô hình sử dụng.

+5

Tôi có phải là người duy nhất sử dụng [array_key_exists] (http://ca.php.net/manual/en/function.array-key-exists.php) thay vì đặt cho loại công cụ này không? – AlexV

+1

* (sidenote) * 'isset' không phát hiện phím * có thể bị thiếu *. Sử dụng 'array_key_exists' cho điều đó. Hãy thử '$ arr = array ('notMissing' => NULL);' with 'isset' – Gordon

+1

@AlexV @Gordon: Tôi không nghĩ rằng nó quan trọng vì giá trị mặc định là NULL anyway: P – BoltClock

Trả lời

8

Nhà điều hành @ chặn thông báo lỗi và sử dụng nó có khả năng thiết lập mã của bạn cho các lỗi khác và hành vi không mong muốn mà sẽ khó theo dõi. Vì vậy, nó chắc chắn nhất là một antipattern.

Vì vậy, tôi rất thích bit thứ hai. Nó làm cho nó rõ ràng hơn nhiều

  • rằng nó có thể không có mặt trong mảng, và
  • những gì giá trị mặc định là nếu nó không có mặt

Để làm cho nó ngắn gọn hơn, bạn có thể sử dụng các ternary toán tử điều kiện ?:, như đã thấy trong Mark Baker's answer. Hơi ít mã và nhiều ký hiệu hơn nhưng ý nghĩa được công nhận rõ ràng.

+1

Tôi hiểu. Việc sử dụng @ an toàn có thể đánh lừa các nhà phát triển khác sử dụng nó ở những nơi sai. –

4

Hoặc

$value = (isset($array['possibly_missing_key'])) ? $array['possibly_missing_key']: null; 
+1

+1 Nếu sử dụng PHP> = 5.3, bạn có thể sử dụng mẫu mới ngắn hơn: 'isset ($ array ['possible_missing_key'])?: Null;' – webbiedave

+4

@webbiedave: Không, điều đó sẽ trả về kết quả của 'isset (.. .) 'và không phải là giá trị mảng thực tế. – BoltClock

+0

@webbiedave: phiên bản ngắn có hoạt động trong trường hợp này không? Nó sẽ không trả về giá trị của 'isset()' (tức là đúng hay sai) thay vì chính biến đó? – Spudley

1

Bỏ qua cảnh báo chắc chắn là một antipattern; do đó, có, đó là một mô hình chống (và tôi có thể đảm bảo rằng nếu bạn tìm hiểu để ngăn chặn cảnh báo, một trong số họ sẽ trở lại và cắn bạn ở phía sau, nếu không tồi tệ hơn).

Ngoài ra, trong khi phiên bản thứ hai có nhiều chi tiết hơn, nó cho biến chưa được khởi tạo một trạng thái đã biết (hoặc có thể được sử dụng để xử lý vấn đề, nếu biến được cho là được điền).

1

Lựa chọn thứ ba:

$value = (isset($array['key']) ? $array['key'] : null); 

Tôi biết điều này không trực tiếp trả lời câu hỏi; Tôi sẽ đặt nó làm bình luận, ngoại trừ nó thực sự cần phải được định dạng. Ý tưởng ở đây là nếu bạn đang cố gắng làm cho mã của mình ngắn hơn bằng cách sử dụng một lớp lót thay vì khối khác, thì bạn vẫn có thể lấy nó thành một lớp lót ngắn gọn bằng cách sử dụng toán tử bậc ba, cho bạn những điều tốt nhất của cả hai thế giới.

+0

Đó không thực sự là một lựa chọn thứ ba, đó là một định dạng khác nhau của tùy chọn 2 (vì nó có chức năng giống nhau). Bạn sẽ nói rằng 'if (x) {something}' và 'if (! X) {} else {something}' là hai giải pháp khác nhau, bởi vì chúng không được viết theo cùng một cách? – Piskvor

+0

@Piskvor - hm, đó là một chút cầu kỳ. Đó là cú pháp khác nhau, vì vậy tôi sẽ nói rằng có nó là một lựa chọn thứ ba, ngay cả khi nó có hiệu quả giống với mã ban đầu của mình. Nhưng quan điểm của tôi là cung cấp một cách để làm điều đó mà không sử dụng '@', vì đó dường như là câu hỏi của anh ta. – Spudley

+0

Vâng, tôi sắp xếp hàng rào về điều này. Cú pháp là khác nhau, nhưng nó làm điều tương tự. Bạn đúng rằng nó ít tiết, trong khi vẫn giữ chức năng. (Tôi đoán nó nói thêm về nitpicking của tôi kêu gọi hơn về các câu hỏi trong tầm tay;)) – Piskvor

1

Khối thứ hai của mã (hoặc phương án thay thế của Mark Baker sẽ hoạt động giống hệt nhau) sẽ tốt hơn. Tôi không hoàn toàn chắc chắn về PHP, nhưng trong nhiều ngôn ngữ lập trình khác, chỉ đơn giản là bỏ qua một biến sẽ gần như chắc chắn ném một lỗi. Ít nhất với khối thứ hai bạn đang khởi tạo biến cho một số giá trị hoặc vị trí bộ nhớ.

Tính năng triệt tiêu lỗi nên được sử dụng phổ biến hơn nếu bạn mong đợi một hàm sẽ ném lỗi dự kiến ​​vào sản phẩm cuối cùng (tuy nhiên, phần lớn thời gian này sẽ không xảy ra).

Chúc may mắn!
Dennis M.

6

Thực tế, biến thể isset là chống mẫu.Nếu bạn chỉ sử dụng isset($var)?$var:NULL với ý định ngăn chặn "lỗi", thì bạn đã không đạt được gì ngoài việc sử dụng cú pháp thích hợp để loại bỏ lỗi. Nó có cùng kết quả, nhưng ít đọc được hơn.

Mọi người đang tranh luận về điều đó vì nhận thức "sạch sẽ" và vì sử dụng isset là tối ưu hóa vi mô. Tránh @ và sử dụng isset như thay thế muối cú pháp chỉ là lập trình giáo phái hàng hóa.

+0

"lập trình giáo phái hàng hóa" lol – BoltClock

+0

Cảm ơn bạn đã đề cập đến một cái nhìn trái ngược. –

+0

@ IvoDanihelka: Thực ra tôi muốn rút lui, và thêm một ** lớn tất cả phụ thuộc **. Không có một mẫu nào phù hợp với tất cả các trường hợp sử dụng. Linh hoạt không tôn giáo về isset/@, sử dụng công cụ tốt nhất cho công việc trong tầm tay. – mario

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