PHP の strpos() は曲者?

2016年9月19日 23:09

strpos は、文字列内の部分文字列が最初に現れる場所を見つける PHP の関数。他の言語でいうところの indexof() のようなもの……と言いたいところだが、ツイートにもあるとおり、その挙動は微妙に異なる。たとえば、JavaScript の場合、

var text = 'I have an apple.';
console.log(text.indexOf('apple'));      // 10
console.log(text.indexOf('orange'));    // -1

というように、部分文字列が存在する場合はそのインデックス番号を、存在しない場合は -1 を返す。ところが、PHP の strpos() で同じことをやっても、存在する場合の結果は同じなのに、存在しない場合に -1 ではなく false を返すのだ。

$string = 'I have an apple.';
echo strpos($string, 'apple');      // 10
echo strpos($string, 'orange');    // false

まぁここまでは許容範囲だと思いたいが、単純な if 文の場合に不都合が生じる。

$string = 'I have an apple.';
if (strpos($string, 'I')) {
    echo 'exists';
} else {
    echo 'does not exist';
}

上記のケースだと文字列 'I have an apple.' に部分文字列 'I' が存在しているので、結果は 'exists' となると期待しがちだが、実際には 'does not exist' となる。理由はもちろん、返されたインデックス番号が 0 であり、この if 文が false になるからだ。

あとは……引数に(誤って)数値を指定してしまった場合の挙動もあるが、それについてはすでにツイートに書いているとおりなので割愛する。