26. CSVデータの読み込み

CSVファイルの読み込み

CSVとは

CSV(Comma Separated Value) は、「 , 」(カンマ) でデータを区切り、複数行にしたフォーマットです。Excelの表のように効率のよいデータ管理ができます。

csv
コーヒー,120
紅茶,150
ほうじ茶,90

fgetcsv()

CSVデータの読み込みはfgetcsv() が便利です。読み込んだデータは配列として返されます。セパレーターはデフォルトでカンマ区切りになっています。

配列 = fgetcsv(ファイルリソース, 長さ, セパレーター)

CSVファイルの用意

ファイル構成

item/
    ├── data/
    │         └── items.csv
    └── list.php

「data」フォルダに「items.csv」を作成します。

データカラム(キー)

1行目はデータのカラムになる行で、連想配列のキーになります。

items.csv
name,price

データ

items.csv

2行目以降は、実際のデータになります。

name,price
コーヒー,120
紅茶,150
ほうじ茶,100

多次元配列の作成

CSVファイルを多次元配列として読み込みましょう。

  [
      ['name', 'price'],
      ['コーヒー', '120'],
      ['紅茶', '150'],
      ['ほうじ茶', '100'],
  ]

ファイル読み込みメソッド定義

ファイル読み込みのメソッド loadItems() を定義し、指定したファイルを開きます。

function loadItems($file_path)
{
    if (!file_exists($file_path)) return;
    $file = fopen($file_path, "r");
}

while文で繰り返し

while文で fgetcsv() を繰り返し、一時変数に追加します。確認のため一次変数を return で返しておきます。

function loadItems($file_path)
{
    if (!file_exists($file_path)) return;
    $file = fopen($file_path, "r");

    // 一時変数
    $rows = [];
    // 繰り返し
    while ($data = fgetcsv($file)) {
        $rows[] = $data;
    }
    fclose($file);
    
    var_dump(rows);
}
結果

var_dump() の結果を確認してみましょう。

array(4) {
  [0]=>
  array(2) {
    [0]=>
    string(4) "name"
    [1]=>
    string(5) "price"
  }
  [1]=>
  array(2) {
    [0]=>
    string(12) "コーヒー"
    [1]=>
    string(3) "120"
  }
  [2]=>
  array(2) {
    [0]=>
    string(6) "紅茶"
    [1]=>
    string(3) "150"
  }
  [3]=>
  array(2) {
    [0]=>
    string(12) "ほうじ茶"
    [1]=>
    string(3) "100"
  }
}

連想配列に変換

完成形のデータ

読み込んだ多次元配列を、連想配列とした多次元配列に変換してみましょう。

[
    ['name' => 'コーヒー', 'price' => 120],
    ['name' => '紅茶', 'price' => 150],
    ['name' => 'ほうじ茶', 'price' => 100],
]

キーの取得

array_shift() でキーの取得

現在の配列は1行目がデータのキーになっているので、array_shift() を使って取得します。

function loadItems($file_path)
{
...
    while ($data = fgetcsv($file)) {
        $rows[] = $data;
    }
    fclose($file);

    $keys = array_shift($rows);
    var_dump($keys);
...
}

キーの確認

var_dump() で表示されたキーを確認してみましょう。

array(2) {
  [0]=>
  string(4) "name"
  [1]=>
  string(5) "price"
}

多次元連想配列に変換

array_combine() で連想配列

array_combine() は、キーの配列と値の配列から連想配列に変換します。

連想配列 = array_combine(キーの配列, 値の配列);

foreachで繰り返し

array_combine() で連想配列に変換し、foreachで多次元配列に追加します。

function loadItems($file_path)
{
...
    $keys = array_shift($rows);

    $values = [];
    foreach ($rows as $row) {
        // 連想配列を多次元配列 $values に追加
        $values[] = array_combine($keys, $row);
    }
...
}

データを返す

array_combine() で連想配列に変換し、foreachで多次元配列に追加します。

function loadItems($file_path)
{
...
    $keys = array_shift($rows);

    $values = [];
    foreach ($rows as $row) {
        // 連想配列を多次元配列 $values に追加
        $values[] = array_combine($keys, $row);
    }

    return $values;
...
}

HTML表示

ファイル読み込み実行

「items.csv」のパスを定義して loadItems() で実行し、var_dump() で結果を表示してみましょう。

$file_path = "../data/item.csv";

$items = loadItems($file_path);
var_dump($items);

foreach でHTML表示

データを確認したら、HTML表示します。endforeach で繰り返して連想配列のキーでデータを表示します。

<h3 class="h3">商品一覧</h3>
<dl>
    <?php if ($items) : ?>
    <?php foreach ($items as $item) : ?>
        <dt><?= $item['name'] ?></dt>
        <dd><?= $item['price'] ?>円</dd>
    <?php endforeach ?>
    <?php endif ?>
</dl>
結果

商品一覧

コーヒー
120円
紅茶
150円
ほうじ茶
100円

ソース

items.csv
name,price
コーヒー,120
紅茶,150
ほうじ茶,90
list.php
<?php

// お知らせ情報読み込み
function loadItems($file_path)
{
    if (!file_exists($file_path)) return;
    $file = fopen($file_path, "r");

    $rows = [];
    while ($data = fgetcsv($file)) {
        $rows[] = $data;
    }
    fclose($file);

    // キーの取得
    $keys = array_shift($rows);

    // 連想配列
    $values = [];
    foreach ($rows as $row) {
        $values[] = array_combine($keys, $row);
    }

    return $values;
}

// ファイルパス
$file_path = "../data/item.csv";

$items = loadItems($file_path);
?>

<!DOCTYPE html>
<html lang="jp">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>商品一覧</title>
</head>

<body>
    <h3>商品一覧</h3>
    <dl>
        <dt>コーヒー</dt>
        <dd>120円</dd>
        <dt>紅茶</dt>
        <dd>150円</dd>
        <dt>ほうじ茶</dt>
        <dd>100円</dd>
    </dl>
</body>

</html>

PHP超入門