カテゴリー

キーワード

 
> 【PHP】 CSVをいい感じにイン...

【PHP】 CSVをいい感じにインポートする方法を紹介します


2015 年 2 月 16 日 投稿    view: 45878
タグ:
このエントリーをはてなブックマークに追加

PHP アイキャッチ

こんにちは、伊藤です。
初めての記事です。

よろしくお願いします。


本日は、【CSVを読み込んでいい感じにインポートする方法】を紹介します。

そもそもCSVとは??

CSVとは簡単に言えば、カンマ区切りのテキストデータのことです。


"名前","性別","¥n","ito","男性","¥n","sugio","不明"


みたいな状態のことですね。

アプリケーションを問わず、データのやり取りをするために互換性を高めた形式です。


CSV形式のファイルは、Excelで開かれることが多いですね。

このときExcelが『これはCSV形式である』と判断し、カンマで区切られたテキスト(文字列)を、いつも見ている『あの』表のような形式で見せてくれます。


もちろんテキストデータですから、メモ帳やテキストエディタなど様々なアプリケーションで開くことも可能です。

つまり、大量のデータを扱うのにもってこいなファイル形式ってことですね。

(実際は文字化けなど厄介なことも多いですが、ここでは割愛)


CSV形式でインポート

で、本題です。

私が最近、使用しているPHPの標準クラスです。

PHP5.1以上を利用しているなら、迷わず『SplFileObject』を利用する方がいいと思います。


改行は、『¥n』。
各文字は『,(カンマ)』

で区切られているので、


    // ファイル取得

    $filepath = "../file/test.csv"
    $file = new SplFileObject($filepath); 
    $file->setFlags(SplFileObject::READ_CSV);
    
    // ファイル内のデータループ
    foreach ($file as $key => $line) {

        foreach( $line as $str ){

            $records[ $key ][] = $str ;
        }

    }

    echo "<pre>";
    print_r( $records );
    echo "</pre>";

かなりスッキリ記述できます。

これは、『標準クラス』っていうキーワードを知らないと、出てこない情報かもしれません。


ちなみに、explodeを使ってもできないことはありませんが、ちょっとした問題があります。


"xxx","y,y,y","zz¥nzz"


のようなデータだった場合、区切り位置がおかしくなってしまうんですね。

一応、コードを紹介しておきますが、以下のような感じです。


    $file = "../file/test.csv";
    $csv = fopen( $file, "r" );
    $line = explode( "¥n", $csv );

    foreach( $line as $key => $val ){
        
        $calam = explode( ",", $val );

        foreach( $calam as $str ){

            $records[ $key ][] = $str ;
        }
    }

    echo "<pre>";
    print_r( $records );
    echo "</pre>";

文字のエンコードとか全然していないので、文字化け必至の状態です。

使わない方がいいですが、一応、参考に紹介しました。


ついでに言うと、『SplFileObject』を使用したときの方がパフォーマンスは良いようです。

参考:http://blog.fenrir-inc.com/jp/2014/07/php-csv.html

10万件のデータの処理時間とメモリ使用量を色んな方法で記載しておりました。


最後にMySqlを使用してデータベースに全行一括INSERTしてみます。


    // ファイル取得
    $filepath = "../file/test.csv";
    $file = new SplFileObject($filepath); 
    $file->setFlags(SplFileObject::READ_CSV);

    // 全行のINSERTデータ格納用
    $ins_values = "";

    

    // ファイル内のデータループ

    foreach ( $file as $key => $line ) {

    
        // 配列の値がすべて空か判定
        $judge = count( array_count_values( $line ) );
        
        if( $judge == 0 ){
            
            // 配列の値がすべて空の時の処理
            continue;
        }
        
        // 1行毎のINSERTデータ格納用
        $values = "";

        foreach ( $line as $line_key => $str ) {
            
            if( $line_key > 0 ){

                $values .= ", ";
            }

            // INSERT用のデータ作成
            $values .= "'".mb_convert_encoding( $str, "utf-8", "sjis" )."'";
        }
        
        if( !empty( $ins_values ) ){ 

            $ins_values .= ", ";
        }

        $ins_values .= "(". $values . ")";
    }


    $sql_insert = "INSERT INTO テーブル名 ( カラム01, カラム02, カラム03 ) VALUES " . $values;
    mysql_query( $sql_insert, $connect );

はい。

実際の運用ではINSERTするカラムがあらかじめ決まってなかったり、1行ずつのINSERTが必要だったり、重複データのチェックが入る場合など色々なパターンがあると思います。


その辺りはいい感じにカスタマイズしてください。

あと、運用中のソースではないので、しっかり出力テストもしてくださいね。


まとめ

今回、このテーマを選んだのは、ちょっとした因縁(?)があったからです。


営業職からSE業へ転身して間もない頃、あるシステムの会議で


顧客情報はCSVでインポート、エクスポートの両方できるようにしてください


と言われたことがあります。

当時、メールフォームを作るので精一杯だった私に、その言葉はモールス信号に等しく…。(理解不能だったという意味です、笑)


もしかしたら、あのときの私と同じ状況に陥っている人がいるかもしれない。

そういう勝手な使命感から、このテーマを選びました。

もし、お役に立てればうれしい限りです。


というわけで次回は、CSVエクスポートについて書いてみたいと思います。


【3/5追記】書きました⇒:【PHP】データをCSVでいい感じにエクスポートする方法


では、またお目にかかります。

 

 

 


カテゴリー

タグ
この記事が気に入りましたら、是非、他の方にもシェアしてください。
このエントリーをはてなブックマークに追加
関連記事