fgetcsv は便利な関数だが、Windowsデータとの連携に問題がある。
WindowsからCSVをアップロードする場合、Shift-JIS がほとんどだと思われる。
一方、fgetcsv関数はロケール設定を考慮するため、システムのロケールとCSVファイルの文字コードが一致していないと正しく解析されない。
色々調べたが、レンタルサーバでもしっかり動かすため、代替関数を作成した。
あきらはメインコントロールのクラスに定義している。
// File Get CSV function fgetcsv( &$fh, $test = false ) { if ( feof( $fh ) ) return false ; $csv = '' ; while ( ! feof( $fh ) ) { $csv .= mb_convert_encoding( fgets( $fh ), 'UTF-8', 'SJIS-win' ) ; if ( ( ( preg_match_all( '/"/', $csv, $matches ) ) % 2 ) == 0 ) break ; } $values = array() ; $temp = preg_replace( '/(?:x0Dx0A|[x0Dx0A])?$/', ',', $csv, 1 ) ; preg_match_all( '/("[^"]*(?:""[^"]*)*"|[^,]*),/', $temp, $matches ) ; for ( $i = 0 ; $i < count( $matches[ 1 ] ) ; $i++ ) { if ( preg_match( '/^"(.*)"$/s', $matches[ 1 ][ $i ], $m ) ) { $matches[ 1 ][ $i ] = preg_replace( '/""/', '"', $m[ 1 ] ) ; } $values[] = $matches[ 1 ][ $i ] ; } return $values ; }
クラス内で以下の様に使う。
$fh = fopen( $path ) ; while ( ( $data = $this->fgetcsv( $fh ) ) !== false ) { ... } fclose( $fh ) ;
まず、コードありがとうございます。
ただ、コードをコピペしたとき、
> $temp = preg_replace( ‘/(?:x0Dx0A|[x0Dx0A])?$/’, ‘,’, $csv, 1 ) ;
の¥が普通の円マークではなくうまく動作せずにはまりました・・・。
¥をキーボードから普通に入力したら動きましたが。