MyMiniCity踏んでください!!

ただいま絶賛MyMiniCity参加中です.是非リンクを踏んでください!!(笑
June 23rd, 2006

続: 「プログラム等、内部の文字エンコーディングは決めておくべき」の返信

(Read: 14205)
Add to Hatena Bookmark

参照: yohgaki's blog - プログラム等、内部の文字エンコーディングは決めておくべき
コメントのコメントです.
長くなったのでまたトラックバックで行きます.
内部エンコーディングとはプログラムの内部で利用する文字エンコーディングのこと言っています。そしてこのエンコーディングは決めておくべき、と言うことです。


これは意味わかりますし,同意です.
が,

> PHPの場合、私がコメントにも書いているように、mbstringは内部的にはUnicodeで文字列を取り扱っています。

は実際のところmb_convert_encoding()など変換系の関数だけじゃないでしょうか?
ソースを追いかけた感じ,mb_convert_encoding()は内部的にphp_mb_convert_encoding()を経由し,libmbf内でフィルターオブジェクトみたいなものを作成し,一旦UNICODEに変換してから変換しているように見えます(若干自信なし

しかし例えばmb_strlen()はmbfl_strlen()に渡りますが,その後文字エンコード毎にあるフィルターのテーブルを元にカウントしていっているだけに見えます.
つまり,大垣さんおっしゃる「mbstringは内部的にはUnicodeで文字列を取り扱っています。」で推測されるようなUNICODE変換は行われていません.
内部的にUNICODEだといかなる処理も変換がかかるものではないのでしょうか?
つまり,

mbstringは基本的に内部文字エンコードはない,変換系の処理を行うときのみUNICODEを経由し,変換される.

ということだと思います.


PHPの文字列型の変数はバイナリです。PHP6ではバイナリと文字列を区別するようになりますが、PHP4/5ではプログラム内部で利用する文字エンコーディングは自由に決められます。


変数はバイナリなのに,なぜプログラム内部で利用する文字エンコーディングは自由に決められるんでしょうか?
まさかすべての変数を

という風にすることを言っているわけではないでしょうし;)

実際決められないからShift_JISやISO-2022-JPでスクリプトを書いたときに誤動作する場合が出てきます(--zend-multibyteを指定してもどちらの文字エンコードでも誤動作します)

実際にどうやって明示的にPHPに文字エンコーディングの指定をするのでしょうか?

・mbstring.internal_encodingはmbstringのデフォルトエンコーディングを決めるだけです.
・default_charsetはContent-Typeでcharsetとして出力されるだけ

ですね.mbstringはくどく書いたのでdefault_charsetの例を挙げておきます.


$ php -r '
var_dump( ini_get( "default_charset"));
var_dump( htmlentities( "あいうえお"));'
string(0) ""
string(50) "ããããã"

$ php -ddefault_charset=UTF-8 -r '
var_dump( ini_get( "default_charset"));
var_dump( htmlentities( "あいうえお"));'
string(5) "UTF-8"
string(50) "ããããã"

$ php -r '
var_dump( ini_get( "default_charset"));
var_dump( htmlentities( "あいうえお", ENT_QUOTES, "UTF-8"));'
string(0) ""
string(15) "あいうえお"

$ php -ddefault_charset=UTF-8 -r '
var_dump( ini_get( "default_charset"));
var_dump( htmlentities( "あいうえお", ENT_QUOTES, "UTF-8"));'
string(5) "UTF-8"
string(15) "あいうえお"
これdefault_charsetをUTF-8にしても正しく処理されないのはバグになるのでしょうか?
私が知る限り,それ以外にPHP 5.1.4までには少なくとも文字エンコードを指定するところは無いと思います(当然各関数内の挙動を一時的に返るような引数は除きます
また,使用頻度の高いPCREなどの外部ライブラリのいくつかはマルチバイトを正しく扱えません.
これを含めてPHPと考えると

「PHPは完全に内部エンコードを指定できないため,内部挙動に気をつけないと思わぬ文字化けなどが発生する」

となると思います.
もし勘違いがあれば引き続きご指摘いただければと思います.


▼ この記事へのコメント ▼
----
は実際のところmb_convert_encoding()など変換系の関数だけじゃないでしょうか?
ソースを追いかけた感じ,mb_convert_encoding()は内部的にphp_mb_convert_encoding()を経由し, libmbf内でフィルターオブジェクトみたいなものを作成し,一旦UNICODEに変換してから変換しているように見えます(若干自信なし
----

mbstringの場合、全てのエンコーディング変換はUnicodeを経由しています。ですからEUC-JP->SJIS, EUC-JP->UTF-8の様に専用コンバータを作らなくても良いようになっています。

mbstringの内部で文字エンコードがどう処理されているか?を説明したいのではなく、プログラム内部での文字エンコードは統一すべきということです。

ついでにmbstringのことを書いたのはmbstringも似たような構造になっているよ、ということです。(mbstringをアプリの一つと捉えると)

ということで本題とは違うのであまり気にしないでください。

ところで内部エンコーディングとは今のPHPでは設定で決める物ではありません。jokagiさんも書いているように補助する機能は付いていますが、プログラマが自分で責任を持って管理するようになっています。

現在はプログラマが内部エンコーディングを決める(PHP6は選択できず、Unicodo、バイナリどちらか)物なのでmbstring.internal_encodingを設定してしていれば普通に使っているとプログラム内部のエンコーディングはmbstring.internal_encodingになるので難しく考えなくても良いのでは?

どちらにしてもmbstringユーザなら内部エンコーディングを決めるなら普通はmbstring.internal_encodingを設定すると思います。

今のPHPに言語的に内部エンコーディングがないのはPHPユーザなら誰でも知っていること(?)なのでPHPの内部エンコーディングとmbstring.internl_encodingが関係ないのでは、とか考える必要も無いと思いますがどうでしょう?

「PHPは完全に内部エンコードを指定できないため,内部挙動に気をつけないと思わぬ文字化けなどが発生する」

文字化けだけなら良いのですがセキュリティ上の問題になることも在ります :)

ブログなので前後の文脈は「行間を読んで」もらうとして、これはPHPに限ったことではなく文字エンコーディングの取り扱いミスはセキュリティ上の問題になる、という事が重要でそれに対する対策として内部エンコーディングは統一したほうがよいですよ、と言うことです。

ちらっとしか見てませんが、strlen、strpos、substr、strwidth系の関数もwchar = UCS4 を経由している気がします。
つまり、文字列はバイナリだけどmbの関数が必要に応じてUnicodeに変換している感じでしょうか。

yohgakiさんのは書いてる途中です.すみません.

あきをさん>>

php-version/ext/mbstring/mbstring.c
読むと全然違うことがわかります.

https://www.codeblog.org/gonzui/markup/php-5.1.0/ext/mbstring/libmbfl/mbfl/mbfilter.c?q=mblen_table#l656
encoding->mblen_table が無い側の方を追ってました orz

でもmb_substr_count、mb_strpos、mb_strwidthはUnicode経由のような気がします(違ったらどうしよう^^;;

昨日からext/mbstring読み直してます
ついでにメモ作り出しました.
結論としては私が思っていたより
yohgakiさんとあきをさんおっしゃるとおりUNICODE(UCS-4)に変換される場面は多そうでした.
私の主張がどちらかというと間違っていたことを謝ります.すみません.

今のところ私の認識では大体で言うと,内部でフィルターを生成してmbfl_no_encoding_wchar
辺りを使ってるものはUNICODE(UCS-4)を使用しているように見えます.
どれ位の関数が使ってるのかわからないけどあきをさんがあげた関数以外にもまだあるかもしれないですね.

解析に使用した資料はもうちょい資料がまとまったら公開使用と思います.

で,internal_encodingがらみとかについては質問してみたいことがあるので,もう少しお待ちください.
今日の午後から明日の夜くらいまでうちでネットができない(ルーターが1個しかないけど引っ越し先にサーバーを持って行くことになった
ので(苦笑

トピックの参照元

▼最近のトピック

▼ 人気のトピック


< 過去の記事 [ 6All Categories ] 新しい記事 >
Powered by gsblog (customize)

[ POST ] [ AddLink ] [ CtlPanel ]

Subscribe blog

Bookmark blog

About me

about me

応援しています

我が息子が産まれたアクア・バースハウス(東京都世田谷区にある助産院)を応援しています.

翻訳のお仕事

腕に自信がある方,修行をしたい方はこちらをどうぞ.

2006 calendar

6月
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
| Day | Month | Year |

Powered by RRDTOOL.

Archives

Categories

Links


Mail to admin

人気ブログランキングへ RSS feed meter for http://blog.poyo.jp/ Search Engine Optimization
blogpeople.netに登録!! スカウター : よくきたblog

My Google news

My Google News

Related site

ころんころん♪ べびぽよ フォト蔵Wiki
string(40) "/categ-1/year-2006/month-6/id-1151032953"