【PHP】
strpos、mb_strposで
日本語がヒットしない、マッチしない、
検索できない時の対処法

2022-06-30
先日、PHPで「strpos()」や「mb_strpos()」を使っていて、日本語を含む文字列を検索すると、なぜかヒットしない、マッチしない、検索できない、という事がありました。

英数字はヒットするし、スペルミスもないのに~と頭を抱えてしまいました。

ここでは、その時の意外な原因と解決方法を備忘録を兼ねてメモっています。

ヒントとなった記事はこちら。大変助かりました。

\項目をタップするとジャンプできます/

strpos、mb_strposで
日本語がヒットしない、マッチしない、
検索できない原因は?

結論から書くと、今回の原因はファイルの文字コードが「ShiftJIS」だったことでした。

この時の作業内容は、ファイルAからファイルBを読み込み、特定の文字列の有無をstrpos関数やmb_strpos関数で調べるといったもの。

作業ファイルAは「UTF-8」形式でファイル作成していたのですが、読み込むファイルBは自動生成ファイルで、文字コードを確認していませんでした。

調べてみたところ、ファイルの文字コードによって1文字のバイト数は異なるそう。

半角英数字は「UTF-8」でも「ShiftJIS」でも1バイトですが、日本語(全角文字)は「ShiftJIS」で2バイト、「UTF-8」では3~8バイトの可変長になっているのだそうです。

strpos関数では、1文字を1バイトとして計算しています。

mb_strpos関数では、1文字で可変長のマルチバイトな日本語に対応している、というわけですね。

ですが、文字コードの異なる「UTF-8」「ShiftJIS」間では、正しく動作しません。

解決方法

「UTF-8」「ShiftJIS」など、異なる文字コードファイル間でデータを扱う場合は、正しく取り出せるデータ形式に変換する必要があります。

読み込むファイルの文字コードを「UTF-8」にすることでも解決できますが、今回は「mb_convert_encoding()」を使って「ShiftJIS」形式のデータを「UTF-8」形式に変換することで解決できました。

「ShiftJIS」ファイルを生成するたびに、文字コードを変更する手間が省けます。

PHP

ob_start();
readfile('sample.txt');
$txt = ob_get_contents();
ob_end_clean();
$txt = mb_convert_encoding($txt,"utf-8","sjis-win");
「ob_start()」「ob_end_clean()」で読み込むファイルのデータを保存しておき、「mb_convert_encoding()」で文字コードを変換しています。

これで、strpos関数でもmb_strpos関数でも、日本語を含む文字列を検索することができました。

SHARE

このサイトについて

「Web Work Plus」はWEB制作・ビジネスのちょい足し情報メデイアです。ちょっとしたハテナをプラスに変える役立つ備忘録を発信中!