PHP の mbstring.language と internal_encoding でビックリした件

いやー久しぶりにビックリしたわ。さすが PHP.

mbstring について何の設定もしていない状態で有効にしてある PHP を用意して以下のコードを動かしてみてください。

.htaccess

AddType application/x-httpd-php .php
php_value mbstring.language Japanese

mbstring.language.php

<?php
print "<pre>";
echo PHP_VERSION."\n";
print_r( mb_get_info() );
mb_internal_encoding( 'euc-jp' );
print_r( mb_get_info() );
print "</pre>";

マニュアル

PHP: mb_language - Manual

によると

  • mbstring.language は mbstring.internal_encoding を設定するので mbstring.internal_encoding は mbstring.language のあとで設定しろ
  • language が Japanese の場合は internal_encoding は EUC-JP が自動でセットされる1

と書かれています。

ということは 1回目の mb_get_info() も 2回目も

   [internal_encoding] => EUC-JP

になるはずなんだけど、これ

EUC-JP になったりならなかったりする

というステキな動作をします。え? なんで? まったく分からない。何の変更も加えていないこのスクリプトを何度も実行していると、1回目の mb_get_info() の出力が変化します2

どういうことやねん

というか、

こんな中途半端な機能ない方がマシです。おっかなくて使えたもんじゃない。

「internal_encoding とか mail_charset とか必要な設定を各自が確実に行いなさい」と言うだけでよくね? language を設定する意味ってなんなの?

ちなみに確認は

  • PHP 5.1.6@CentOS 5.1
  • PHP 4.4.8@FreeBSD 6.3

で行いました。

さらにちなみに、Twitter でブータレてたら同じ経験をしている人がやはりいました。

Twitter / ryota ichie: @wtnabe 自分もphq4で経験あります!結局原因…

結構昔からずっとこの動作なんでしょうねぇ3。すっげー気持ち悪い。まぁ、

internal_encoding をはじめ、必要な項目には確実に明示的に値をセットしてから使いましょう

ってことですな。

  1. もちろん euc-jp 以外に自分で設定し直すことは可能 

  2. 毎回表示が変わるような派手な動きはたぶんしません。辛抱強く何回も実行してみてください。 

  3. なんで自分が今頃これに気づいたかというと、以前は長いこと PHP 4.2.x を使っていたからです。mbstring.language は 4.3 で登場した設定項目なのです。 

More