2010年12月5日日曜日

PHPの本当にあった怖い話(1)

筆者はPHPを仕事で使うようになって5年経ちますが、それは自慢になりません。
何故なら、未だに裏切られます。

結論から言いましょう。


$aaa = range("0","9");
$bbb = range("a","z");
$ccc = array_merge( $aaa, $bbb );
$ddd = array_search( "a", $ccc );


この$dddには何が入るのか?10が入って欲しいですよね?
0です。

この理由がいきなり説明できる人は、PHPの仙人もしくは関係者でしょう。
師匠もしくは、インサイダーと呼ばせてください。

実は最初のrangeが曲者です。
これは"0"と"9"を指定したにも関わらず、intの配列を作ります。
結果、$cccの中身にはintとstringが混在していることになります。

まだ前フリです。

そしてarray_searchで何が起こるのか?

"a"を探せ、って言ってるのに、intval("a")==0 で0番目が一致しちゃってるのです。

ありえなくね?

結論として、前述の例では、rangeとarray_searchの挙動の共犯です。

PHPは、こういった「暗黙の型変換」が大量にあり、warningすら出ません。
http://www.php.net/manual/en/types.comparisons.php

sortについては、これを反映して、「比較「型」の強制」があります。
http://www.php.net/manual/en/function.sort.php

しかし、array_searchには無いわけです。

初心者のうちは助けられることが多いと思いますし、
それを意図しての型変換でしょう。
しかし、中級になったとたん裏切られるのです。

これを期待通りに可動させるには、rangeの結果にstrvalを通す必要があります。


$aaa = array_map( "strval", range("0","9") );
$bbb = range("a","z");
$ccc = array_merge( $aaa, $bbb );
$ddd = array_search( "a", $ccc );


ありえなくね?