次のような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");