phpを使ってる人なら1回はstrpos関数を使ったことがあると思います。 そして罠にも引っかかったことがあると思います。。。
実装
<?php $haystack = '吾輩は猫である'; $needle = '吾輩'; if (strpos($haystack, $needle)) { var_dump('夏目漱石'); }
何も表示されません
<?php $haystack = '吾輩は猫である'; $needle = '猫'; if (strpos($haystack, $needle)) { var_dump('夏目漱石'); }
夏目漱石が表示されます
なぜか
strposのドキュメントを見てみましょう
strpos(string $haystack, string $needle, int $offset = 0): int|false
返り値に0も入ってしまうのが原因でした。
<?php $haystack = '吾輩は猫である'; $needle = '吾輩'; var_dump(strpos($haystack, $needle));
0が返ってきます。
<?php $haystack = '吾輩は猫である'; $needle = '猫'; var_dump(strpos($haystack, $needle));
9が返ってきます。
吾輩は
でUTF-8で9バイトをとっているのでその値が返ってきます。
正しい実装はこちら
<?php $haystack = '吾輩は猫である'; $needle = '吾輩'; if (strpos($haystack, $needle) !== false) { var_dump('夏目漱石'); }
!== false
を入れる必要があったんですね
こんなこともう気にしないでいいんだ。そう、php8ならね
php8のstr_containsを使えば全部忘れちゃって問題なしです!
シンプルに文字が含まれるかどうかboolで返してくれます
str_contains(string $haystack, string $needle): bool
<?php $haystack = '吾輩は猫である'; $needle = '吾輩'; if (str_contains($haystack, $needle)) { var_dump('夏目漱石'); }
夏目漱石が表示されます
さよならstrpos。今までありがとう。 そしてこんにちはstr_contains