Що означає використання однієї труби "|" У аргументі функції робити?


82

Візьмемо, наприклад, такий код:

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

Використовується один аргумент, але я надаю список варіантів, розділених символом однієї труби.

  • Що саме відбувається зі значенням аргументу у функції?
  • Чи можу я використовувати те саме у своїх власних функціях?
  • Так так, і чи є в цьому переваги від того, що, скажімо, передавання масиву замість цього?

Це побітова версія АБО, звичайна версія мала б дві труби.
adeneo

32
Знаєте, я не можу зрозуміти, як деякі коментатори принижують готовність користувачів задавати питання ... До того, що на це потрібно користувачеві з репутацією 210 тисяч!
nickhar

5
Цікаво, якщо користувач з репутацією> 5000 на SO, який не задавав жодних питань, насправді не має запитань чи вважає задавання питань ознакою слабкості?
Пітер

15
Давайте також усвідомимо, що символи важко шукати.
Леві Моррісон,

9
@nickhar .. і що для того, щоб потрапити на цю сторінку документації, вам насамперед потрібно було б ознайомитись із конкретним терміном, який якимось чином і полягає у
суті

Відповіді:


136

Побітові оператори

Побітові оператори модифікують біти задіяних значень. Порозрядне ORосновному ЗОШ разом кожен біт лівий і правий аргумент. Наприклад:

5 | 2

Перекладається в біти / двійковий файл як:

101 | 10

Що призведе до:

111

Оскільки:

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

І як ціле число це представлення 7, яке саме те, що ви отримуєте, якщо:

echo 5 | 2;

За словами Едді Ізарда ... Прапор!

Як зазначає Ігнасіо, це найчастіше використовується в PHP (та інших мовах) як спосіб поєднання декількох прапорів. Кожен прапор зазвичай визначається як константа, значення якої зазвичай встановлюється цілим числом, яке представляє лише один біт з різним зміщенням:

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

Тоді, коли ви ORразом, вони працюють кожен зі своїм зміщенням і ніколи не зіткнуться:

FLAG_A | FLAG_C

Перекладається на:

1 | 100

Отже, ви в кінцевому підсумку вмикаєте:

101

Що представляє ціле число 5.

Тоді весь код, який повинен зробити - код, який буде реагувати на різні прапори, що встановлюються - є наступним (з використанням побітового розряду 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
}

Зрештою це просто полегшує читання, називаючи константи, і, як правило, більш оптимальним, спираючись на цілі значення, а не на рядки чи масиви. Ще одна перевага використання констант полягає в тому, що якщо вони коли-небудь неправильно вводяться при використанні, компілятору випадає краща ситуація, коли він повідомляє і видає попередження ... якщо використовується значення рядка, він не може знати, що щось не так.

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 за чудовий пост. У мене було багато проблем, обгорнувши це все, але ваше пояснення та приклади допомогли мені це зрозуміти набагато простіше, ніж якби я щойно прочитав документацію PHP. Дуже дякую.
загадковий ツ

3
@cryptic не турбуйтеся - адже пошук того, що ви не можете назвати, досить хитрий - тепер, якщо б Google прийняв абзаци пояснень та приклади як пошуковий термін :)
Pebbl,

4
Чудове пояснення та приклади! +1
Sablefoste,

16

Ви передаєте аргумент, який є побітовим АБО декількох прапорів . Ви можете використовувати оператор де завгодно.


10
Дякую, @Ignacio, що пам’ятаєте, що не всі в SO є експертом у програмуванні або навіть знають, з чого почати з документації.
Sablefoste,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.