PHP strposの罠 マルチバイトに対応する

PHPの関数 strpos() はある文字列から指定された文字列を探し、見つかった場所のインデックスを返す関数ですが、
マルチバイトには対応していません。
このことを理解せずに使っていると思わぬ結果が帰ってくることがあります

$message = "helloりんご🍎だよ";
$apple_str_index = strpos($message, "りんご");
$apple_mark_index = strpos($message, "🍎");
$dayo_index = strpos($message, "だよ");

返ってきて欲しい値はそれぞれ5と8と9だと思いますが、実際の値は5と14と18です。(utf-8の場合)
文字コードというのはバイト列で表されますが日本語や絵文字などの文字は1バイトでは表しきれません。
そこで文字コードはマルチバイトで表現することで様々な種類の文字を表示することができています。

しかしstrposなどの関数はマルチバイトには対応していないのでマルチバイトの文字列、例えば”りんご”はそれぞれ3バイトずつで合計9バイトのため9文字分とみなします。
視覚的な一文字を一文字として捕らえたい場合はマルチバイトに対応した mb_strpos を使うべきです。(mbはマルチバイトの略)

$message = "helloりんご🍎だよ";
$apple_str_index = mb_strpos($message, "りんご");
$apple_mark_index = mb_strpos($message, "🍎");
$dayo_index = mb_strpos($message, "だよ");

こうすることで返ってくる値はそれぞれ5と8と9になります