ダンプ関数で出力した文字列が一致している様に見えるにも関わらず文字列同士の比較が不一致となる場合があります。これは例えば次のコードです。
<?php $a = 'ほげ'; $b = 'ほげ'; echo '$a===$b: ',($a === $b ? 'true' : 'false')."\n"; echo ' $a: '.$a."\n"; echo ' $b: '.$b."\n"; /* $a===$b: false $a: ほげ $b: ほげ */
Online PHP editor | output for cTkJ7#上記コードのデモ
PHP の文字列比較はバイト単位の比較であり、こうなっている時は大体、制御文字や文字として表現不可能なデータが混じっている時です。例えばCSVのヘッダーの1列目周りででこれが起きる時は十中八九 BOM 関連です。他にも決まったバイト数でトリミングされたことのあるデータなどもこれに陥りやすいです。
何か違う文字が入っている、というところまではvar_dump
関数を使うだけでもたどり着けます。例えば先ほどのコードならば次の様になります。
<?php $a = 'ほげ'; $b = 'ほげ'; var_dump([ '$a===$b' => $a === $b, '$a' => $a, '$b' => $b, ]); /* array(3) { ["$a===$b"]=> bool(false) ["$a"]=> string(6) "ほげ" ["$b"]=> string(7) "ほげ" } */
string(6)とstring(7)でバイト数が異なることがわかります。更に踏み込んで紛れたバイナリが何に由来するものなのか調査する場合には、見えないけど何かあるだけでなく何が入っているのかを確認する必要があります。この確認にはbin2hex
関数が便利です。
bin2hex
関数は与えられたバイナリのデータを16進数表現にして返します。これを用いると先ほどのコードは次の様になります。
<?php $a = 'ほげ'; $b = 'ほげ'; var_dump([ '$a===$b' => $a === $b, '$a' => bin2hex($a), '$b' => bin2hex($b), ]); /* array(3) { ["$a===$b"]=> bool(false) ["$a"]=> string(12) "e381bbe38192" ["$b"]=> string(14) "e381bb0fe38192" } */
Online PHP editor | output for cfrfl#上記コードのデモ
これで片方にだけ謎の 0x0F が紛れていることがわかりました。ここから先の調査はケース次第でまちまちです。大体バイナリと心あたりのあるものを手当たり次第にググって検証して、といったことをします。