index

2010年 3月
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 31        
2010年 4月
        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    
2010年 5月
 
            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
  31            

アレ

str_getcsv() と setlocale()   ▽20100409a #プログラミング #PHP

PHP には fgetcsv() とか str_getcsv() なんつー無精くさい関数があって, 名前を見た通りファイルや文字列を CSV として解釈して配列で返してくれるというもの.

「CSV」って特に定まった規格のあるフォーマットじゃないんで, しかも一番有名なのが一番変則的な Excel 出力 CSV なんで, マトモに読み書きしようとすると地味にけっこう大変だったりする.

んが,この getcsv() はなぜかよく出来ていて, Excel 形式の(データ中に " を含む場合は "" と書く,とかの)データもさくさく読めちゃったりするので, カジュアルに使うには楽出来て良かったりする.

(もちろん悪意ユーザからの攻撃データとかが想定される場面ではもっと注意して制限したフォーマットを使うべき).


んが,こういう文字列を解析する系の関数では必ず出て来る日本語エンコーディング問題.

自分の手元のサーバでは普通に読めたファイルが, 他の場所ではなぜか日本語を含む一部の項目だけ読み落とされた,なんて事象が起きた. しかも,他の場所で Web から動かした場合のみで, 同じ処理をコマンドラインから動かすと期待通りに動く.

しかも日本語が全てダメというのでもなく,読めてる項目と読めてない項目がある……

コマンドラインと Web で挙動が違うというと, 例えば違う設定ファイルを読んで動いてるかーとかなんだけど, 全部の日本語が文字化けってわけではなく一部は正常に読めてるので, エンコーディング設定とかってわけではなさそう.

これが単に文字化けしてるとかなら, PHP 設定の mbstring.internal_encoding とファイル自体のエンコーディングが合ってないとか, そういう原因だろうと推測できるのだけど……


というわけで軽く Web で調べると, 「fgetcsv() は日本語に対応していない」とかってのを見かける. いえそんなことはありません.うちの環境では読めてるし.

次に「日本語は "" で括らないとダメ」というのが. いえそんな(ry ……でも読めてる項目は "" で括られていて読めてない項目は括られていないってのが判明.

"" の有無で,内部で違う処理になってるんだろうか. たしかに,"" がなければ単に次の , を探せばいいだけだが, "" の場合は \" とかのエスケーピングを避けながら終端 " を探さないといけないので, 内部処理は違ってそうだ.


というわけでソースを読んでみると,確かに処理が違っている. php-5.3.2/ext/standard/file.c の 2150行目あたり. mblen() で日本語を意識しながらぽちぽちと文字を飛ばして行っている処理がありました.

で,この mblen() はどういうエンコーディングを扱ってるんだ? と思ったら, これが標準ライブラリをそのまま読んでるだけで( ext/standard/php_string.h ), 環境設定の mbstring.internal_encoding とかを意識してはいないみたい.

ってことで,そっち方面のエンコーディングを変更するために, setlocale() を使うってわけなのねー.


setlocale( LC_ALL, 'ja_JP.UTF-8' );


で,期待通りの動作になりました. Web と CLI で挙動が違うのは,環境変数 LANG によるものでした,ということで.


答えが判ってから探すと情報が見つかる罠. はっはっは.

それにしても mbstring 設定があるけどそっちは mbstring モジュール用で, 他の箇所では locale 設定をきちんとしとけ,とか, いかにも PHP らしいテキトーっぷりです.ははは.


CATV+スカパーe2 →CATV+スカパー光   ▽20100405a #日記

スカパーe2 からスカパー HD に置き換えるなんて計画を考えていたら,「スカパー光 ハイビジョン放映を 5月から」とかそういうw

誰だよあたしの脳内にロガー仕込んだの……

さて,スカパー光ってのがうちの B フレッツで使えるかどうかがわからんのでそこは要確認なのだが, もし可能なら,前回のスカパー HD で視聴と思っていたチャネルが全部スカパー光で HD 放映されることになる.

スカパー光の録画保存はスカパー HD と同様に DTCP-IP だそうなので, スカパー用のアンテナを設置しないで全てを実現出来る.わーお,ゆめのようー.

ちなみになぜフレッツやってるのに要確認かというと, うちのフレッツは「ベーシック」という特殊なタイプで (名前がベーシックなのに特殊とかおかしいと思う > NTT), この手の家庭向けサービスは何かとハブられたり 「一部地域」だったり「設置料がバカ高」だったりするのだ.


さて,そんなこんなで光がいいにゃーとか思ってたら, G+ HD は e2 で既に HD 放映という事実が判明.

わっふう! とばかりに e2 で G+ HD を契約 IN, ついでにフジテレビ ONE/TWO/NEXT を契約 OUT!

でも G+ HD で NASCAR 第5戦を録画したら SD だったw まぁそれでも CATV の SD よりキレイだったけどさw


さて,そんなこんなで仕事がようやく緩くなってきた昨今, ふと CATV の方からメールが来ているのを見ると, 4月1日から CATV で G+ HD 放映開始だとw

なんだか弄ばれているような気がする昨今. まぁ世の中が確実に HD に移行しつつあるということで.


その後,NASCAR 第6戦を録画したら,しっかり HD だった. アメリカのシリーズは独占契約でなかったりするとこういう事があるからなぁ. 放映チャネルすら別だったりするんだし,SD/HD 混在くらいなんともないぜ.おそろしす.


index