1. ホーム
  2. php

[解決済み] 関数の引数でシングルパイプ '|' を使用するとどうなりますか?

2023-06-08 09:06:16

質問

例えば、次のようなコードがあるとします。

phpinfo(INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);

引数は1つですが、オプションのリストを1つのパイプ記号で区切って提供しています。

  • 関数内の引数値には、具体的に何が起こっているのでしょうか。
  • 同じものを自分の関数で使うことはできますか?
  • その場合、どのように、また、代わりに配列を渡すと言った場合よりも利点があるのでしょうか?

どのように解決するのですか?

ビット演算子

ビット演算子は、関係する値のビットを変更します。ビット演算子 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
}

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

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.