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

サービスプロバイダとは

Laravelをやっていて、次に分かり難かった概念、サービスプロバイダについて。 アプリケーション開発にはデータベース、ファイル操作、ログ操作など様々な操作があり、個別のビジネス処理以外で共通化できる …

no image

POP3を使ったメール受信

メールの送信と比べると、プログラムで描く頻度は少ないですが、メールの受信について。 Contents1 POP3サーバー2 プログラムにてPOP3サーバーと通信3 PHPにてメールを取得する場合 PO …

no image

phpQueryを使ったスクレイピングに関して

以前、スクレイピングに関してはこのエントリーでも紹介したとおり、phpに標準で入っているDOMDocumentを使う方法が一番楽です。 ところがデータによってはXMLで解析するため目的とする要素を取得 …

no image

composer最低保証のバージョンを管理

自分の開発端末ではPHPのバージョンが7.1何ですが、上げなければいけないサーバーのバージョンが7.0だったりして、

みたいなエラーが …

no image

switch(true)イディオム

switch文は通常、文字や数字で分岐をさせることが多いですが、実は条件式を入れることも可能です。 私の場合、正規表現を動的に変えたいケースがあり、検索したところ似たケースがありました。 【JavaS …

アーカイブ