Co robi używanie pojedynczej rury '|' W argument funkcji zrobić?

82

Weźmy na przykład następujący kod:

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

Używany jest pojedynczy argument, ale podaję listę opcji oddzielonych pojedynczym symbolem potoku.

  • Co dokładnie dzieje się z wartością argumentu w funkcji?
  • Czy mogę używać tego samego we własnych funkcjach?
  • Czy tak, jak i czy są z tego korzyści w porównaniu z przekazaniem zamiast tego tablicy?
tajemnicze ツ
źródło
To jest bitowa wersja OR, zwykła wersja miałaby dwie potoki.
adeneo,
32
Wiesz, nie mogę pojąć, jak niektórzy komentatorzy umniejszają gotowość użytkowników do zadawania pytań ... Do tego stopnia, że ​​odpowiedź na to pytanie zajmuje użytkownik z 210 tys. Przedstawicieli!
nickhar
5
Zastanawiam się, czy użytkownik z reputacją> 5000 na SO, który nie zadał żadnych pytań, tak naprawdę nie ma pytań lub uważa, że ​​zadawanie pytań jest oznaką słabości?
Peter,
15
Zdajmy sobie również sprawę, że symbole są trudne do wyszukania.
Levi Morrison
9
@nickhar .. i żeby wylądować na tej stronie dokumentacji, musiałbyś najpierw zapoznać się z konkretnym terminem, który w pewnym
sensie jest sednem

Odpowiedzi:

136

Operatory bitowe

Operatory bitowe modyfikują bity odpowiednich wartości. Bitowe w ORzasadzie OR łączy razem każdy bit lewego i prawego argumentu. Na przykład:

5 | 2

Przetłumaczyłoby się na bity / binarne jako:

101 | 10

Co spowodowałoby:

111

Dlatego:

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

I jako liczba całkowita, która jest reprezentacją liczby 7, która jest dokładnie tym, co otrzymujesz, jeśli:

echo 5 | 2;

Słowami Eddiego Izzarda… Flaga!

Jak stwierdza Ignacio, jest to najczęściej używane w PHP (i innych językach) jako sposób łączenia wielu flag. Każda flaga jest zwykle definiowana jako stała, której wartość jest zwykle ustawiana na liczbę całkowitą reprezentującą tylko jeden bit w innym przesunięciu:

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

Wtedy, kiedy to zrobisz ORrazem, działają one na swoim własnym bitowym przesunięciu i nigdy się nie zderzają:

FLAG_A | FLAG_C

Przetłumaczyć na:

1 | 100

Więc w końcu włączasz:

101

Która reprezentuje liczbę całkowitą 5.

Następnie wszystko, co musi zrobić kod - kod, który będzie reagował na różne ustawiane flagi - jest następujące (używając bitowej 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
}

Pod koniec dnia po prostu ułatwia to czytanie, ponieważ ma nazwane stałe i ogólnie jest bardziej optymalne, polegając na wartościach całkowitych, a nie na łańcuchach lub tablicach. Inną zaletą używania stałych jest to, że jeśli zostaną one kiedykolwiek wpisane błędnie, kompilator jest w lepszej sytuacji, aby o tym powiedzieć i rzucić ostrzeżenie ... jeśli zostanie użyta wartość ciągu, nie ma możliwości dowiedzenia się, że coś jest nie tak.

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.
Pebbl
źródło
5
+1 za świetny post. Miałem wiele kłopotów ze zrozumieniem tego wszystkiego, ale Twoje wyjaśnienia i przykłady pomogły mi to zrozumieć o wiele łatwiej, niż gdybym właśnie przeczytał dokumentację PHP. Dziękuję Ci bardzo.
tajemniczy ツ
3
@cryptic nie martw się - w końcu wyszukiwanie czegoś, czego nie możesz nazwać, jest raczej trudne - teraz, gdyby tylko Google zaakceptował akapity wyjaśnień i przykładów jako wyszukiwane hasło :)
Pebbl
4
Świetne wyjaśnienie i przykłady! +1
Sablefoste
16

Przekazujesz argument, który jest bitowym LUB wielu flag . Możesz używać operatora w dowolnym miejscu.

Ignacio Vazquez-Abrams
źródło
10
Dziękuję @Ignacio, że pamiętasz, że nie każdy w SO jest ekspertem od programowania, a nawet wie, od czego zacząć dokumentację.
Sablefoste