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

220 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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;` と書くのか?
**`配列[] = 値;` は「配列の最後に追加する」という意味**
```php
$arr = [1, 2, 3];
$arr[] = 4;
// 結果: $arr = [1, 2, 3, 4]
$fruits = ['りんご', 'バナナ'];
$fruits[] = 'みかん';
// 結果: $fruits = ['りんご', 'バナナ', 'みかん']
```
CSVの場合も同じ:
```php
$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);`
### 配列の要素を変更する方法
配列の中身を変更したい場合、いくつかの方法があります:
```php
// 方法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;` を使うのか?
**「この行は無視して次へ」という意味**
```php
foreach ($rows as $row) {
if ($row[0] == '削除したいID') {
continue; // ← ここで次のループへジャンプ。以下の処理はスキップされる
}
$newRows[] = $row; // ← 削除対象じゃない行だけここに到達する
}
```
**つまり**: 削除対象の行は「新しい箱に入れない」ことで削除を実現する。