PHPのロケール*1まわりについて調査したので、これをまとめてみます。
この記事は「ロケールの影響を受ける関数 - Sarabande.jp」を掘り下げたものです。masakielasticさん、ナイスな記事をありがとうございます。
PHPの文字列型と文字エンコーディング
他のモダンなLL言語と異なり、PHPは文字列の文字エンコーディングに関して何も仮定せず、単なるバイト列として管理しています。つまり、文字エンコーディングの取り扱いは各関数の実装に委ねられています。
下記の通り、これはマニュアルにも記述があるのですが、実に残念なことです。
残念ながら、PHP の各関数が文字列のエンコーディングを判断する方法はまったく統一されていません。
とはいえ、引用元の文章では各関数と文字エンコーディングの関係を下記のように大別しています。
- 文字エンコーディングを仮定せず、文字列をバイト列とバイトオフセットで扱う関数(substr, strposなど)
- 内部エンコーディングに従うか、または引数で文字エンコーディングを指定する関数(htmlentities, mbstring関数全般)
- ロケール設定に従う関数(本稿の話題、strcasecmpなど)
- UTF-8など特定の文字エンコーディングを前提とする関数(u修飾子利用時のPCRE関数など)
これを見ると、それぞれの関数の出自によって挙動が変わっているようです。PHP本体の実装として、OSの機能に頼ったり他所から持ってきたライブラリに頼ったりと実装がバラバラであることが混乱の一因だといえるでしょう。
本稿では、3番目の分類にある「ロケール」について詳しく見ていきます。