SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【php】fgetcsv()でShift_JISのCSVをそのまま読みたい

問題

Shift_JISのCSV(Excelで作ったの)をそのままphpのfgetcsv()で読みたいんだけど、無理?

答え

fgetcsv()はロケールの設定に依存する

つまり、OSの方を変えるといろんなCSVを読むことができる。

ja_JP.sjisというロケール設定が通常存在しないが、警告されつつも設定することはできる。

# localedef -f SHIFT_JIS -i ja_JP ja_JP.sjis
character map `SHIFT_JIS' is not ASCII compatible, locale not ISO C compliant

これで、SHift_JISのファイルに対しては、setlocale(LC_ALL, 'ja_JP.sjis') することでfgetcsv()できるようになる。

setlocale(LC_ALL, 'ja_JP.sjis');
$fp = fopen('/tmp/sjis.csv', 'r');
while ($line = fgetcsv($fp)) {
    //読み取ったデータはShift_JISなので、必要に応じて変換して
    mb_convert_variables('UTF-8', 'sjis-win', $line);
    var_dump($line);
}

手元にあるサーバーを覗いてみたら、いろいろと対応できそうな雰囲気です。

# ls /usr/share/i18n/charmaps/
ANSI_X3.110-1983.gz    GB2312.gz            IBM868.gz             JIS_C6229-1984-B-ADD.gz
ANSI_X3.4-1968.gz      GBK.gz               IBM869.gz             JIS_C6229-1984-B.gz
ARMSCII-8.gz           GB_1988-80.gz        IBM870.gz             JIS_C6229-1984-HAND-ADD.gz
ASMO_449.gz            GEORGIAN-ACADEMY.gz  IBM871.gz             JIS_C6229-1984-HAND.gz
BIG5-HKSCS.gz          GEORGIAN-PS.gz       IBM874.gz             JIS_C6229-1984-KANA.gz
BIG5.gz                GOST_19768-74.gz     IBM875.gz             JIS_X0201.gz
BS_4730.gz             GREEK-CCITT.gz       IBM880.gz             JOHAB.gz
BS_VIEWDATA.gz         GREEK7-OLD.gz        IBM891.gz             JUS_I.B1.002.gz
CP10007.gz             GREEK7.gz            IBM903.gz             JUS_I.B1.003-MAC.gz
CP1125.gz              HP-ROMAN8.gz         IBM904.gz             JUS_I.B1.003-SERB.gz
CP1250.gz              IBM037.gz            IBM905.gz             KOI-8.gz
CP1251.gz              IBM038.gz            IBM918.gz             KOI8-R.gz
CP1252.gz              IBM1004.gz           IBM922.gz             KOI8-T.gz
CP1253.gz              IBM1026.gz           IEC_P27-1.gz          KOI8-U.gz
CP1254.gz              IBM1047.gz           INIS-8.gz             KSC5636.gz
CP1255.gz              IBM1124.gz           INIS-CYRILLIC.gz      LATIN-GREEK-1.gz
CP1256.gz              IBM1129.gz           INIS.gz               LATIN-GREEK.gz
CP1257.gz              IBM1132.gz           INVARIANT.gz          MAC-CYRILLIC.gz
CP1258.gz              IBM1133.gz           ISIRI-3342.gz         MAC-IS.gz
CP737.gz               IBM1160.gz           ISO-8859-1.gz         MAC-SAMI.gz
CP775.gz               IBM1161.gz           ISO-8859-10.gz        MAC-UK.gz
CP949.gz               IBM1162.gz           ISO-8859-11.gz        MACINTOSH.gz
CSA_Z243.4-1985-1.gz   IBM1163.gz           ISO-8859-13.gz        MIK.gz
CSA_Z243.4-1985-2.gz   IBM1164.gz           ISO-8859-14.gz        MSZ_7795.3.gz
CSA_Z243.4-1985-GR.gz  IBM256.gz            ISO-8859-15.gz        NATS-DANO-ADD.gz
CSN_369103.gz          IBM273.gz            ISO-8859-16.gz        NATS-DANO.gz
CWI.gz                 IBM274.gz            ISO-8859-2.gz         NATS-SEFI-ADD.gz
DEC-MCS.gz             IBM275.gz            ISO-8859-3.gz         NATS-SEFI.gz
DIN_66003.gz           IBM277.gz            ISO-8859-4.gz         NC_NC00-10.gz
DS_2089.gz             IBM278.gz            ISO-8859-5.gz         NEXTSTEP.gz
EBCDIC-AT-DE-A.gz      IBM280.gz            ISO-8859-6.gz         NF_Z_62-010.gz
EBCDIC-AT-DE.gz        IBM281.gz            ISO-8859-7.gz         NF_Z_62-010_1973.gz
EBCDIC-CA-FR.gz        IBM284.gz            ISO-8859-8.gz         NS_4551-1.gz
EBCDIC-DK-NO-A.gz      IBM285.gz            ISO-8859-9.gz         NS_4551-2.gz
EBCDIC-DK-NO.gz        IBM290.gz            ISO-IR-197.gz         PT.gz
EBCDIC-ES-A.gz         IBM297.gz            ISO-IR-209.gz         PT154.gz
EBCDIC-ES-S.gz         IBM420.gz            ISO-IR-90.gz          PT2.gz
EBCDIC-ES.gz           IBM423.gz            ISO_10367-BOX.gz      RK1048.gz
EBCDIC-FI-SE-A.gz      IBM424.gz            ISO_10646.gz          SAMI-WS2.gz
EBCDIC-FI-SE.gz        IBM437.gz            ISO_11548-1.gz        SAMI.gz
EBCDIC-FR.gz           IBM500.gz            ISO_2033-1983.gz      SEN_850200_B.gz
EBCDIC-IS-FRISS.gz     IBM850.gz            ISO_5427-EXT.gz       SEN_850200_C.gz
EBCDIC-IT.gz           IBM851.gz            ISO_5427.gz           SHIFT_JIS.gz
EBCDIC-PT.gz           IBM852.gz            ISO_5428.gz           SHIFT_JISX0213.gz
EBCDIC-UK.gz           IBM855.gz            ISO_646.BASIC.gz      T.101-G2.gz
EBCDIC-US.gz           IBM856.gz            ISO_646.IRV.gz        T.61-7BIT.gz
ECMA-CYRILLIC.gz       IBM857.gz            ISO_6937-2-25.gz      T.61-8BIT.gz
ES.gz                  IBM860.gz            ISO_6937-2-ADD.gz     TCVN5712-1.gz
ES2.gz                 IBM861.gz            ISO_6937.gz           TIS-620.gz
EUC-JISX0213.gz        IBM862.gz            ISO_8859-1,GL.gz      TSCII.gz
EUC-JP-MS.gz           IBM863.gz            ISO_8859-SUPP.gz      UTF-8.gz
EUC-JP.gz              IBM864.gz            IT.gz                 VIDEOTEX-SUPPL.gz
EUC-KR.gz              IBM865.gz            JIS_C6220-1969-JP.gz  VISCII.gz
EUC-TW.gz              IBM866.gz            JIS_C6220-1969-RO.gz  WINDOWS-31J.gz

Windowsで作ったCSVで、機種依存文字が含まれる場合は、こうしてみる。

# localedef -f SHIFT_JISX0213 -i ja_JP ja_JP.sjis

中国語のCSVには GB2312 が使えるかもしれない。

関連するメモ

コメント