LoginSignup
8
10

More than 5 years have passed since last update.

CSVファイルをオブジェクト指向な感じで取り扱う方法

Posted at

次のようなCSVファイルがあったとします。

日付,商品コード,数量
2013-08-01,12345,1
2013-08-01,23456,2
2013-08-02,34567,1

このファイルをPHPでいい感じに取り扱えるコードを書いてみました。

ImportCsv.php
<?php
class ImportCsv 
{
    protected $date;
    protected $code;
    protected $quantity;

    public function getDate()
    {
        return $this->date;
    }

    public function setDate($date)
    {
        $this->date = $date;
    }

    public function getCode()
    {
        return $this->code;
    }

    public function setCode($code)
    {
        $this->code = $code;
    }

    public function getQuantity()
    {
        return $this->quantity;
    }

    public function setQuantity($quantity)
    {
        $this->quantity = $quantity;
    }

    public function getLine()
    {
        $ret = array();

        foreach (self::getSupportedColumns() as $columnName) {
            $ret[] = !is_null($this->$columnName) ? $this->$columnName : '';
        }

        return self::convertArrayToCsv($ret);
    }

    public function setLine($line, $layout = null)
    {
        $columns = self::getSupportedColumns();

        if (is_null($layout)) {
            $layout = self::getHeader();
        }

        if (count($line) !== count($layout)) {
            throw new \InvalidArgumentException('Invalid CSV layout is given');
        }

        foreach ($layout as $key => $column) {
            if (array_key_exists($column, $columns)) {
                $property = $columns[$column];
                $this->$property = trim($line[$key]);
            }
        }
    }

    public static function getHeader()
    {
        return self::convertArrayToCsv(array_keys(self::getSupportedColumns()));
    }

    public static function getSupportedColumns()
    {
        return array(
                '日付' => 'date',
                '商品コード' => 'code',
                '数量' => 'quantity'
        );
    }

    protected static function convertArrayToCsv(array $datas)
    {
        $delimiter = ',';

        $csv = array();
        foreach ($datas as $data) {
            $csv[] = '"' . str_replace('"', '""', $data) . '"';
        }

        return implode($delimiter, $csv);
    }
}

で、読み込むときは

AwesomeAction.php
<?php
    // CSVファイルをUTF-8に変換し、テンポラリファイルに展開
    $buffer = preg_replace("/\r\n|\r|\n/", "\n", mb_convert_encoding(file_get_contents($path), 'utf-8', 'SJIS-win'));
    $fp = tmpfile();
    fwrite($fp, $buffer);
    rewind($fp);

    // CSVファイルを読み込み
    $header = fgetcsv($fp);

    while ($line = fgetcsv($fp)) {
        $csv = new ImportCsv();
        $csv->setLine($line, $header);

        $ret[] = $csv;
    }

    fclose($fp);

    // 取り込んだデータを利用
    foreach ($ret as $row) {
        var_dump($row->getDate());
        var_dump($row->getCode());
        var_dump($row->getQuantity());
    }

で、書き込むときは

AwesomeAction.php
 <?php
   $fp = fopen($path, 'wb');

    // ヘッダを書き込む
    fwrite($fp, ImportCsv::getHeader() . "\r\n");

    // データを書き込む
    fwrite($fp, $csv->getLine() . "\r\n");
8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10