web-dev-qa-db-ja.com

単一のパイプ「|」を使用するとどうなりますか関数の引数で?

たとえば、次のコードをご覧ください。

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

単一の引数が使用されていますが、単一のパイプ記号で区切られたオプションのリストを提供しています。

  • 関数の引数値で正確に何が起こっていますか?
  • 自分の関数で同じものを使用できますか?
  • そうですか、代わりに配列を渡すことよりも、これには利点がありますか?
74
cryptic ツ

ビットごとの演算子

ビットごとの演算子は、関係する値のビットを変更します。ビット単位のORは、基本的に左右の引数の各ビットをORで結合します。例えば:

5 | 2

次のようにビット/バイナリに変換されます:

101 | 10

結果は次のとおりです。

111

なぜなら:

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

また、7の表現である整数としては、次の場合に正確に得られます。

echo 5 | 2;


エディ・イザードの言葉で…旗!

Ignacioが述べているように、これは複数のフラグを組み合わせる方法としてPHP(およびその他の言語)で最もよく使用されます。各フラグは通常、値が通常整数に設定される定数として定義されます別のオフセットで1ビットのみを表します。

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
}

結局のところ、名前付き定数を使用することで読みやすくなり、一般的には文字列や配列ではなく整数値に依存することで最適化されます。定数を使用するもう1つの利点は、使用時に誤って入力された場合、コンパイラが警告を発し、警告するより良い状況にあることです...文字列値が使用されている場合、何かが間違っていることを知る方法がないことです。

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

ビット単位のOR of 複数フラグ である引数を渡します。任意の場所で演算子を使用できます。