[PHP-users 28092] Re: setlocale()が動作しなくなる事がある
Tadashi Jokagi
ml @ elf.no-ip.org
2006年 1月 13日 (金) 03:55:29 JST
上鍵です.こんにちは.
ロケール関連ですが,システムライブラリがマルチバイトに対応してい
る場合(mbrlen()などを持っている場合) ext/standard/php_string.h の
php_mblen というマクロ定義がマルチバイト対応になります.で,
fgetcsv はこのマクロを使用していますので,ロケール依存はその辺りが
ゆえんになるんだと思います.下記関連 URL.
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/mbsinit.3.html
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/mbrlen.3.html
ですが,fgetcsv 自体が
static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t len, const char delimiter TSRMLS_DC)
{
int inc_len;
unsigned char last_chars[2] = { 0, 0 };
↑2 バイト分しかバッファがない
(snip)
PHP_FUNCTION(fgetcsv)
{
char *temp, *tptr, *bptr, *line_end, *limit;
char delimiter = ','; /* allow this to be set as parameter */
char enclosure = '"'; /* allow this to be set as parameter */
const char escape_char = '\\';
(snip)
/* use first character from string */
delimiter = delimiter_str[0];
(snip)
/* use first character from string */
enclosure = enclosure_str[0];
↑delimiter も enclosureも 1 バイトしか保持しない,きめうちエスケープ
文字定義がある
(snip)
if (*bptr == escape_char) {
↑決めうちでエスケープ(バックスラッシュ)チェックがある
という感じでとてもマルチバイト対応とはいえません(ましになったけど
昔と大して変わらない)感じです.少なくとも最後の部分があるので,お
そらく SHIFT JIS で使用する限り問題が発生するんじゃないかと思いま
す.もし OS がロケール Shift_JIS に対応していてかつ CLI 版の PHP
をお持ちでしたら(長いですけど)
■端末が Shift_JIS で動作できる場合
$ echo "漢字,項目,機能,表" | ./php -r 'var_dump( setlocale( LC_ALL, "ja_JP.SJIS")); var_dump( fgetcsv( STDIN, 8192));'
■端末が Shift_JIS で動作しない場合
$ echo "漢字,項目,機能,表" | iconv -f UTF-8 -t Shift_JIS | ./php -r 'var_dump( setlocale( LC_ALL, "ja_JP.SJIS")); var_dump( fgetcsv( STDIN, 8192));' | iconv -f Shift_JIS -t UTF-8
#UTF-8 を自分が使用している端末の適切な文字エンコードに変更してください
とか正常に動作しますか?
#うちはロケールに Shift_JIS(ja_JP.SJIS)がなかったためか glibc のビルド
環境によるのか動作しませんでした
--
----.----1----.----2----.----3----.----4----.----5----.----6----.----7
Tadashi Jokagi/Setagaya city mailto:elf @ elf.no-ip.org
YokukitanaII http://elf.no-ip.org/
Yokukitablog http://blog.poyo.jp/
Yokukitawiki http://wiki.poyo.jp/
PHP-users メーリングリストの案内