Sử dụng một ống đơn có tác dụng gì '| Trong một đối số hàm Làm gì?


81

Lấy ví dụ đoạn mã sau:

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

Một đối số duy nhất đang được sử dụng, nhưng tôi đang cung cấp danh sách các tùy chọn được phân tách bằng một ký hiệu ống đơn.

  • Chính xác thì điều gì đang xảy ra với giá trị đối số trong hàm?
  • Tôi có thể sử dụng thứ tương tự trong các chức năng của riêng mình không?
  • Như vậy có phải như vậy không và có lợi ích gì đối với điều này khi nói truyền một mảng không?

Đó là phiên bản bitwise của OR, phiên bản thông thường sẽ có hai đường ống.
adeneo 11/12/12

32
Bạn biết đấy, tôi không thể hiểu được việc một số nhà bình luận coi thường người dùng sẵn sàng đặt câu hỏi ... Đến mức người dùng có 210 nghìn đại diện mới trả lời được!
nickhar 11/12/12

5
Tôi tự hỏi liệu một người dùng có danh tiếng> 5000 trên SO, người chưa đặt câu hỏi nào thực sự không có câu hỏi hoặc coi việc đặt câu hỏi là dấu hiệu của sự yếu kém?
Peter

15
Hãy cũng nhận ra rằng các biểu tượng rất khó tìm kiếm.
Levi Morrison

9
@nickhar .. và rằng để đất trên trang tài liệu, bạn sẽ phải làm quen với thuật ngữ cụ thể ở nơi đầu tiên, đó là bằng cách nào đó toàn bộ vấn đề của câu hỏi ..
Obmerk Kronen

Câu trả lời:


136

Toán tử bitwise

Toán tử bitwise sửa đổi các bit của các giá trị liên quan. ORVề cơ bản, một bitwise OR kết hợp với nhau từng bit của cả đối số bên trái và bên phải. Ví dụ:

5 | 2

Sẽ dịch sang bit / nhị phân là:

101 | 10

Điều này sẽ dẫn đến:

111

Bởi vì:

1 || 0 = 1
0 || 1 = 1
1 || 0 = 1

Và dưới dạng Số nguyên là đại diện của 7, chính xác là những gì bạn nhận được nếu bạn:

echo 5 | 2;

Theo lời của Eddie Izzard ... Cờ!

Như Ignacio nói, điều này thường được sử dụng nhất trong PHP (và các ngôn ngữ khác) như một cách để kết hợp nhiều cờ. Mỗi cờ thường được định nghĩa là một hằng số có giá trị thường được đặt thành một số nguyên chỉ đại diện cho một bit ở một độ lệch khác:

define('FLAG_A', 1); /// 0001
define('FLAG_B', 2); /// 0010
define('FLAG_C', 4); /// 0100
define('FLAG_D', 8); /// 1000

Sau đó, khi bạn ORkết hợp chúng với nhau, chúng hoạt động trên mỗi bit bù đắp của riêng chúng và sẽ không bao giờ va chạm:

FLAG_A | FLAG_C

Dịch sang:

1 | 100

Vì vậy, bạn sẽ bật:

101

Biểu thị số nguyên 5.

Sau đó, tất cả những gì mã phải làm — mã sẽ phản ứng với các cờ khác nhau đang được đặt — như sau (sử dụng một chút AND):

$combined_flags = FLAG_A | FLAG_C;

if ( $combined_flags & FLAG_A ) {
  /// do something when FLAG_A is set
}

if ( $combined_flags & FLAG_B ) {
  /// this wont be reached with the current value of $combined_flags
}

if ( $combined_flags & FLAG_C ) {
  /// do something when FLAG_C is set
}

Vào cuối ngày, nó chỉ làm cho mọi thứ dễ đọc hơn bằng cách đặt các hằng số được đặt tên và nói chung là tối ưu hơn bằng cách dựa vào các giá trị số nguyên thay vì chuỗi hoặc mảng. Một lợi ích khác của việc sử dụng hằng số là nếu chúng bị gõ nhầm khi được sử dụng, trình biên dịch sẽ ở trong tình huống tốt hơn để thông báo và đưa ra cảnh báo ... nếu một giá trị chuỗi được sử dụng, nó không có cách nào để biết rằng có gì sai.

define('MY_FLAG_WITH_EASY_TYPO', 1);

my_function_that_expects_a_flag( MY_FLAG_WITH_EASY_TPYO );

/// if you have strict errors on the above will trigger an error

my_function_that_expects_a_flag( 'my_string_with_easy_tpyo' );

/// the above is just a string, the compiler knows nowt with 
/// regard to it's correctness, so instead you'd have to
/// code your own checks.

5
+1 cho bài đăng tuyệt vời. Tôi đã gặp rất nhiều khó khăn khi xoay quanh vấn đề này, nhưng lời giải thích và ví dụ của bạn đã giúp tôi hiểu nó dễ dàng hơn nhiều so với việc tôi chỉ đọc tài liệu PHP. Cảm ơn rât nhiều.
khó hiểu ツ

3
@cryptic không phải lo lắng - sau khi tất cả tìm kiếm một cái gì đó bạn không thể tên là khá khó khăn - bây giờ nếu chỉ Google chấp nhận đoạn văn giải thích và ví dụ như cụm từ tìm kiếm :)
Pebbl

4
Giải thích và ví dụ tuyệt vời! +1
Sablefoste 11/12/12

16

Bạn đang chuyển một đối số là bitwise HOẶC của nhiều cờ . Bạn có thể sử dụng nhà điều hành bất cứ nơi nào bạn thích.


9
Cảm ơn bạn, @Ignacio, vì đã nhớ rằng không phải tất cả mọi người tại SO đều là chuyên gia về lập trình, hoặc thậm chí biết bắt đầu từ đâu với tài liệu.
Sablefoste
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.