PHP8.0で文字列の中から部分文字列の存在をチェックする関数、str_contains() が追加されました。
『いや、そんな関数すでにあるでしょ?』と思った人も多いでしょう。
そのとおりで strpos() でまったく同じ処理ができます。しかも、関数名だけがちがうだけと言っていいくらいプログラムコードが似ている。
str_contains() の使い方
str_contains() の使い方はかんたんです。これまで使ってきたstrpos()と同時に見てみましょう。
$str = 'xxxabcyyy';
$search = 'abc';
if (false !== str_contains($str, $search)) {
echo 'string [' . $search . '] matches' . PHP_EOL;
}
if (false !== strpos($str, $search)) {
echo 'string [' . $search . '] matches' . PHP_EOL;
}
$search = 'abd';
if (false === str_contains($str, $search)) {
echo 'string [' . $search . '] unmatches' . PHP_EOL;
}
if (false === strpos($str, $search)) {
echo 'string [' . $search . '] unmatches' . PHP_EOL;
}
string [abc] matches
string [abc] matches
string [abd] unmatches
string [abd] unmatches
これだけ見ると、『なんで新しい関数を作った? strpos() でいいじゃん』と思ってしまいます。
str_contains() と strpos() のちがいは戻り値
さっきのサンプルコードでは判定の条件を false で見ました。これだと str_contains() と strpos() にちがいはありません。
(strpos()には3番目のパラメータがあるが、部分文字列存在チェックでは未指定でも良い。)
判定を false で見てれば、関数名だけを strpos から str_contains に変えるだけで済む。
strpos() は本来、部分文字列が見つかった位置を返す関数で、見つからなかったら false を返すのを存在チェックに流用しているに過ぎません。
一方、新しく追加された str_contains() は、true or false を返します。部分文字列の存在チェックに特化した関数。
判定の条件を true で見ることも可能です。
$str = 'xxxabcyyy';
$search = 'abc';
if (true === str_contains($str, $search)) {
echo 'string [' . $search . '] matches' . PHP_EOL;
}
$search = 'abd';
if (true !== str_contains($str, $search)) {
echo 'string [' . $search . '] unmatches' . PHP_EOL;
}
string [abc] matches
string [abd] unmatches
日本語(全角文字)などマルチバイト文字でも使える
忘れるところでした。日本語の文字列でも使えます。
$str = 'こんにちは。田中さん。';
$search = '田中';
if (true === str_contains($str, $search)) {
echo 'string [' . $search . '] matches' . PHP_EOL;
}
$search = '佐藤';
if (true !== str_contains($str, $search)) {
echo 'string [' . $search . '] unmatches' . PHP_EOL;
}
string [田中] matches
string [佐藤] unmatches
str_contains() を追加した理由は、関数の意味に忠実になるため
PHPを使ってる人にとっては、部分文字列の存在チェックで strpos() を使うのは当たり前です。基本のキといっても過言じゃない。
ですが、その他のプログラム言語からやってきた人、プログラミングを始めたばかりの人は混乱します。
関数はFunctionの数学用語的な和訳ですが、Functionの本来の意味は『機能』です。その機能を表す関数名と使い方が離れているとよろしくありません。
プログラマーは関数名から機能を想像して使ったり覚えたりするので、strpos() のように一瞬思考が止まる、直感的じゃないものは避けます。
あえて新しい関数を追加した理由はここでしょう。『string contains』は『文字列を含む』という意味なので関数名で一目瞭然です。
前々から名と実が一致しないのは違和感を持っていて、PHP8でやっと修正したというところじゃないかな?
関数の戻り値でどういうものを返すかにも意味がある。
strpos() で存在チェックをしたとき、存在したときの答えが複数ある(見つかった場所の位置)のも直感的じゃない。
存在チェックの答えは Yes, No がシンプルで分かりやすく、存在したか(true)、しないか(false)の答えを返すstr_contains()はそれが考慮されている。
PHP公式ドキュメント