互換性のために作った array_intersect_key を見直していて、ふと不思議な文をマニュアルに見つけた。それが下の一文。
「二つの要素は、 (string) $elem1 === (string) $elem2 の場合のみ等しいとみなされます。言い替えると、厳密なチェックが行われるため、文字列表現が同じである必要があります。」(つたない英語力だが英語サイトも同様)
ref)
http://www.php.net/manual/en/function.array-intersect-key.php一瞬「え?」です。
ここで配列の基本の幾つか。
- key は、整数 または 文字列です。
- 整数の標準的な表現形式である場合、 そのように解釈されます (つまり、"8" は 8 として解釈されます。一方、 "08" は "08" として解釈されます)。
ref)
http://www.php.net/manual/ja/language.types.array.phpつまり、厳密であろうと曖昧であろうと、key は「重ならない」と思っていたわけです。つまり array(1 => value1, "1" => value2) と定義しても array(1 => value2) と解釈される。そのため array_key_exists に strict が無くても問題はなく、isset のような恐ろしく曖昧なものより信用していたんですね。それなのに array_intersect_key の場合は、string への型変換後に厳密なチェック云々とはどういうこっちゃ? と。array の性質上すでに解決済みのハズ。
で、この前書いた。
PHP:array_key_exists のバグ?
http://zombiebook.seesaa.net/article/228944224.htmlがまざまざと蘇る訳です。
しょーがなので、イヤイヤ試すと案の定といいますか……。
(※ 今回は Windows, php 5.2.4 のみで検査です)
array(
'2147483647' => int 0,
2147483647 => int 0,
);
あらまあやっちゃってるよ。コノ人。上記2のルールが解決されてない。そう思うと array_key_exists には strict だとどこにも書いてないが、strict だとしたらそっちのほうが正しい動きをしていた訳だ。むしろ array が悪い子じゃん。まあ、内部的にいつ解釈されるのか知りませんが、var_dump の結果です。
本来なら。
array(
2147483647 => int 0,
);
になるはず。
これ放置するのオカシイよね? こんな基本的な事ホントに既知じゃないの? 5.2 までスルー? それとも私が何か読み落としてる?
既知かどうか、色々調べようかと思ったけど……。
なんだかどうでも良くなってきた。ハァ……。php 嫌いじゃないんだけどねぇ。なんだか型宣言が必要な言語が懐かしくなってきたよ。
ちなみに1
int max は設定できる。これを設定しなおすとどうなるか不明。
ちなみに2
キーが想定できない場合 $ary[$key] で走査する部分は危険かもしれない。具体的には for や foreach よりも each でペアを取った方が安全。もう調べる気力も試す気力もないが。
個人的に以下はエラーにすべきだと。検査してはいるが存在自体気分悪い。
key に浮動小数点数値を指定すると、 その値は integer に切り詰められます。キーとして TRUE を使用した場合、 整数型の 1 がキーとして解釈されます。 キーとして FALSE を使用した場合、 整数型の 0 がキーとして解釈されます。 キーとして NULL を使用した場合、 空の文字列として評価されます。
posted by HiFa at 00:31
| 愛知 ☁
|
Comment(0)
|
TrackBack(0)
|
ときどきPHP
|

|