Files
PHP-EM-OOP/ヒント.md
2026-10-22 08:48:13 +09:00

6.7 KiB
Raw Blame History

EmployeeAccess.php 実装のヒント

まず理解すべきこと:「配列の中に配列」

CSVファイルは「表形式」のデータです。これをPHPで扱うときは「配列の中に配列を入れる」形になります。

イメージ

CSVファイル:
1610000001,山田太郎,yamada@gmail.com
1610000002,鈴木花子,suzuki@gmail.com
1610000003,麻枝史明,maeda@gmail.com

↓ readData()で読み込むと...

$rows = [
    ['1610000001', '山田太郎', 'yamada@gmail.com'],  // 1行目
    ['1610000002', '鈴木花子', 'suzuki@gmail.com'],  // 2行目
    ['1610000003', '麻枝史明', 'maeda@gmail.com']    // 3行目
]

重要: $rowsは「箱の中に箱が入っている」状態。外側の箱($rows)の中に、3つの小さな箱(各行)が入っている。


add(新規登録)の考え方

質問:既にある配列に、新しい1行を追加するには?

今のCSVファイル($rows):
['1610000001', '山田太郎', 'yamada@gmail.com']
['1610000002', '鈴木花子', 'suzuki@gmail.com']
['1610000003', '麻枝史明', 'maeda@gmail.com']

↓ ここに新しい行を追加したい!

['1610000004', '田中五郎', 'tanaka@example.com']  ← これを追加

考え方の手順

  1. まず「箱の中身」を全部取り出す
    → $rows = $this->readData();
    → 今、$rowsには既存の3行が入っている

  2. 新しい1行(箱)を作る
    → 新しいID、名前、メールアドレスを1つの配列にする
    → $newRow = [新しいID, 新しい名前, 新しいメールアドレス];

  3. 大きな箱($rows)の一番後ろに、小さな箱($newRow)を入れる
    → $rows[] = $newRow;
    → これで$rowsには4行になる!

  4. 箱の中身をCSVファイルに全部書き戻す
    → $this->writeData($rows);

なぜ $rows[] = $newRow; と書くのか?

配列[] = 値; は「配列の最後に追加する」という意味

$arr = [1, 2, 3];
$arr[] = 4;
// 結果: $arr = [1, 2, 3, 4]

$fruits = ['りんご', 'バナナ'];
$fruits[] = 'みかん';
// 結果: $fruits = ['りんご', 'バナナ', 'みかん']

CSVの場合も同じ:

$rows = [
    ['1', '山田', 'yamada@example.com'],
    ['2', '鈴木', 'suzuki@example.com']
];

$newRow = ['3', '田中', 'tanaka@example.com'];
$rows[] = $newRow;  // ← 最後に追加!

// 結果:
$rows = [
    ['1', '山田', 'yamada@example.com'],
    ['2', '鈴木', 'suzuki@example.com'],
    ['3', '田中', 'tanaka@example.com']  // ← 追加された
];

つまり: 新しい行(箱)を、全体の配列(大きな箱)の最後にポンと入れるイメージ。


update(更新)の考え方

質問:既にある行の、特定の項目だけを変更するには?

今のCSVファイル:
['1610000001', '山田太郎', 'yamada@gmail.com']
['1610000002', '鈴木花子', 'suzuki@gmail.com']  ← この行の名前とメールを変更したい
['1610000003', '麻枝史明', 'maeda@gmail.com']

↓

['1610000001', '山田太郎', 'yamada@gmail.com']
['1610000002', '鈴木次郎', 'suzuki_new@example.com']  ← 変更された!
['1610000003', '麻枝史明', 'maeda@gmail.com']

考え方の手順

  1. 箱の中身を全部取り出す
    → $rows = $this->readData();

  2. 1つずつ箱を開けて、目的のIDか確認する
    → forループで $rows[0], $rows[1], $rows[2] ... と順番に見ていく
    → 各行の $rows[$i][0] がID

  3. 目的のIDが見つかったら、その行の名前とメールを上書きする
    → $rows[$i][1] = 新しい名前;
    → $rows[$i][2] = 新しいメールアドレス;

  4. 見つかったらフラグを立てる
    → $found = true;

  5. ループ後、見つからなければエラー
    → if (!$found) throw new RuntimeException(...);

  6. 箱の中身をCSVファイルに全部書き戻す
    → $this->writeData($rows);

配列の要素を変更する方法

配列の中身を変更したい場合、いくつかの方法があります:

// 方法1: for文でインデックスを使う
for ($i = 0; $i < count($rows); $i++) {
    if ($rows[$i][0] == '検索したいID') {
        $rows[$i][1] = '新しい名前';  // インデックスで直接変更
    }
}

// 方法2: foreachで参照渡し(&を使う)
foreach ($rows as &$row) {
    if ($row[0] == '検索したいID') {
        $row[1] = '新しい名前';  // &があるので元の配列が変わる
    }
}
unset($row); // 重要: 参照を切断しないと、後で$rowを使ったときに元の配列が意図せず書き換わる

// 方法3: foreachでキーを使う
foreach ($rows as $key => $row) {
    if ($row[0] == '検索したいID') {
        $rows[$key][1] = '新しい名前';  // キーで元の配列にアクセス
    }
}

注意: 普通の foreach ($rows as $row) だと、$rowはコピーなので元の$rowsは変わりません。


delete(削除)の考え方

質問:特定の行だけを除外した新しい配列を作るには?

今のCSVファイル:
['1610000001', '山田太郎', 'yamada@gmail.com']
['1610000002', '鈴木花子', 'suzuki@gmail.com']  ← この行を削除したい
['1610000003', '麻枝史明', 'maeda@gmail.com']

↓

['1610000001', '山田太郎', 'yamada@gmail.com']
['1610000003', '麻枝史明', 'maeda@gmail.com']  ← 2行だけ残った

考え方の手順

  1. 箱の中身を全部取り出す
    → $rows = $this->readData();

  2. 新しい空の箱を用意する
    → $newRows = [];

  3. 1つずつ箱を開けて、削除対象じゃないものだけを新しい箱に入れる
    → foreachで各行をチェック
    → IDが一致したら continue;(スキップ)
    → 一致しなければ $newRows[] = $row;(新しい箱に入れる)

  4. 見つかったらフラグを立てる
    → $found = true;

  5. ループ後、見つからなければエラー
    → if (!$found) throw new RuntimeException(...);

  6. 新しい箱の中身をCSVファイルに書き込む
    → $this->writeData($newRows);

なぜ continue; を使うのか?

「この行は無視して次へ」という意味

foreach ($rows as $row) {
    if ($row[0] == '削除したいID') {
        continue;  // ← ここで次のループへジャンプ。以下の処理はスキップされる
    }
    $newRows[] = $row;  // ← 削除対象じゃない行だけここに到達する
}

つまり: 削除対象の行は「新しい箱に入れない」ことで削除を実現する。