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

PHPでの切り上げ誤差問題

PHPを初めて、4年近くたちますがいまだに知らんことが多いですね(爆) 本日は、

になるという非常にビックリな仕様に遭遇・・・ なにや …

no image

PHPで配列の同一性(集合のチェック)

AとBという配列があり、A⊂B つまりは集合のような関係を確かめたいときに下記のようなメソッドを使います。  

no image

エラーハンドリング

エラーが起きた時にPHPだと画面に出ますが(出ない場合は画面が白くなります)、これを検知し、ログに吐いたり任意の処理をできるのがエラーハンドリングです。 フレームワークなどにはほぼこの仕組みが内在して …

no image

PHPでのリフレクション

Javaなどでは結構やりましたが、PHPでも動的にインタンス生成→メソッド呼び出しということをやれるとやれることが一気にふえるため、ちょっとメモです。 Contents1 ソース2 参考リンク ソース …

no image

PHPでの空白削除に関して

PHPで空白を削除する方法についてメモします。 trimについて 空白を削除する関数といえばtrimが何といっても一番有名でしょう。

アーカイブ