skillup

技術ブログ

PHP

mb_convert_encodingに関して(文字コードの自動検出やその周辺)

投稿日:2018年11月18日 更新日:

以前Perlでもやりましたが、文字コードの自動検出に関して。

ちなみにcp932=SJIS-WINです。

参考リンク

Perlでの動的改行コード読み込みに関して+cp932ネタ

PHPの場合、mb_detect_encodingという文字コード検出の関数があるらしいのですが、どうやらあまり当てはまらないらしく、頼れないようです(汗)

PHPの文字エンコーディング検出はアテにならない

今回はテキストファイル(文字コード不明、ただし実際はsjisかutf8)を読み込みutf8に変換するって処理が必要だったんですが、元のエンコーディングがわからないとどうしようもないです。

で、色々調べたところmb_language('Ja')+mb_convert_encoding($file_contents, 'UTF-8','ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN,SJIS');
でいけるようです。mb_convert_encoding($file_contents, 'UTF-8','auto')という手法もありますが、autoよりも実際の文字コードを列挙するほうが精度が高いようです。

*特にSJIS-WINはSJISより前においたほうがいいようです。SJIS-WINにあってSJISにないものを検知できるので。

mb_convert_encodingで第3引数には元々のエンコーディングを書きますが、これがautoになっていると複数の文字コードからPHPが検出テストを行い、この文字コードであろうという推測を行います。

列挙する場合、先頭の文字コードから順にチェックをしていくようです。だからSJIS-WNをSJISの前にしたほうが都合がいいかもしれません。

(おそらく100%ではないと思います。vimも自動検出機能がありますが、たまに間違えますが、同じことだと思います。だから文字コードがわかっていれば第3引数は文字コードをセットするのが当然無難です。)

が、通常だとSJIS-WINが候補にないのかUnable to detect character encodingというエラーがでてしまいます。

そこでmb_language('Ja')をセットすることでSJIS-WINが検出できるようになります。

mb_convert_encodingのautoが危険な理由

またmb_substrのような関数がありますが、おそらくPHP内部でマルチバイトに対して特殊なフラグを設定しているものと思われます。

ここら辺Perlはしっかりと分けて判定しないくてはいけないので面倒な分、理解せざるを得ませんでした。

参考リンク

Perlの文字コードに関して その1

Perlの文字コードに関して その2

Perlの文字コードについて その3

 

-PHP
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

テンプレートエンジンTwigについて

SmartyにかわるテンプレートエンジンとしてTwig(ツィッグ)を勉強中。 といってもテンプレートエンジンなので基本的なことはほとんど一緒っぽいですが。 Contents1 インストール2 基本的な …

no image

コード静的解析ツールを使った際の気づきなど

最近のプロジェクトでコード静的解析ツール(phpcs,phpmd)を使った際の気づきなど コードを書きながら常時エディタがチェックするタイプのものでないとまず無理(保存するたびでも無理だし、コミット時 …

no image

composerに関して

Javaではライブラリをpomで管理し、mavenを使うことで一括管理していました。 PHPではcomposerがその役割を担っています。 Contents1 composer公式ドキュメント2 co …

no image

CakePHP3でのコレクションに関して

プログラミングにおいて基礎となるのは配列、ハッシュの処理とオブジェクト指向の使いこなしです。 配列、ハッシュの処理に関しては自前でメソッドを書いてもよいですが、バグの温床になりやすいので、ライブラリを …

no image

Laravelのルーティングに関して

Laravelでのルーティングに関して。 惰性で使っていたんですが、これを機にしっかりと整理してみようかと。あくまで頻出パターンのみです。 ディフォルトだとroutes/web.phpが読み込まれます …