web-dev-qa-db-fra.com

Qu'est-ce que l'utilisation d'un seul tuyau '|' Dans un argument de fonction faire?

Prenez par exemple le code suivant:

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

Un seul argument est utilisé, mais je fournis une liste d'options séparées par un seul symbole de canal.

  • Que se passe-t-il exactement avec la valeur d'argument dans la fonction?
  • Puis-je utiliser la même chose dans mes propres fonctions?
  • Est-ce le cas, et y a-t-il des avantages à dire que passer un tableau à la place?
74
cryptic ツ

Opérateurs au niveau du bit

Les opérateurs au niveau du bit modifient les bits des valeurs impliquées. Un OR au niveau du bit OU essentiellement ensemble chaque bit de l'argument gauche et droit. Par exemple:

5 | 2

Se traduirait en bits/binaire comme:

101 | 10

Ce qui entraînerait:

111

Car:

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

Et en tant que nombre entier, c'est la représentation de 7 qui est exactement ce que vous obtenez si vous:

echo 5 | 2;


Dans les mots d'Eddie Izzard ... Drapeau!

Comme l'indique Ignacio, cela est le plus souvent utilisé dans PHP (et autres langages) comme moyen de combiner plusieurs indicateurs. Chaque indicateur est généralement défini comme une constante dont la valeur est normalement définie sur un entier qui représente juste un bit à un décalage différent:

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

Ensuite, lorsque vous OR ensemble, ils opèrent chacun sur leur propre décalage de bits et ne se heurteront jamais:

FLAG_A | FLAG_C

Se traduit par:

1 | 100

Vous finissez donc par allumer:

101

Qui représente l'entier 5.

Ensuite, tout ce que le code doit faire - le code qui réagira aux différents indicateurs définis - est le suivant (en utilisant un AND au niveau du bit):

$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
}

À la fin de la journée, cela rend les choses plus faciles à lire en ayant des constantes nommées, et généralement plus optimales en s'appuyant sur des valeurs entières plutôt que sur des chaînes ou des tableaux. Un autre avantage de l'utilisation des constantes est que si elles sont mal tapées lors de leur utilisation, le compilateur est dans une meilleure situation pour dire et lancer un avertissement ... si une valeur de chaîne est utilisée, il n'a aucun moyen de savoir que quelque chose ne va pas.

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.
118
Pebbl

Vous passez un argument qui est le bit OR de plusieurs drapeaux . Vous pouvez utiliser l'opérateur où vous voulez.

16