Laravel csvファイル読み込み・書き込み・コンバート  課題3・CSVの加工（難易度: 高)

# csvファイル

storage/app/**members.csv**

```php
山田太郎,東京都港区,090-0000-0000

```


# コンバート用csvファイル

storage/app/**members_converted.csv**

```php
0,東京都港区,090-0000-0000
1,東京都杉並区,090-2222-2222
2,東京都豊島区,090-3333-3333
```

# ルーティング

/routes/**web.php**

```php
<?php
Route::get('/csv_sample', 'SampleController@csvSample');

Route::get('/csv_sample', 'SampleController@csvSample');

Route::post('/convert_csv', 'SampleController@convertCsv');
```

# コントローラー

app/Http/Controllers/**SampleController.php**

```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
 
class SampleController extends Controller{

  public function csvSample(){
      // SplFileObjectの作成
      $file = new \SplFileObject(storage_path('app/members.csv'));
 
      // 読み込み設定
      $file->setFlags(
        \SplFileObject::READ_CSV | // CSVを配列形式で読み込む
        \SplFileObject::READ_AHEAD |
        \SplFileObject::SKIP_EMPTY | // 前の行と合わせて、空行があったら読み飛ばす
        \SplFileObject::DROP_NEW_LINE // 改行コードは無視する
      );
      // 1行ずつ読み込んで配列に保存
      $members = [];
      foreach($file as $member){
        $members[] = $member;
      }
      // ビューファイルに出力
      return view('samples.csv_sample', [
        'title' => 'CSV読み込みのサンプル',
        'members' => $members,
      ]);
    }

// ----書き込み------------------------------------------------------
  
     public function csvWrite(Request $request){
 
      $request->validate([
        'user_name' => ['required', 'max:20'],
        'address' => ['required', 'max:100'],
        'phone' => ['required', 'max:20'],
      ]);
 
      $file = new \SplFileObject(storage_path('app/members.csv'), 'a');
 
      $member = [
        $request->input('user_name'),
        $request->input('address'),
        $request->input('phone'),
      ];
 
      $file->fputcsv($member);
 
      // flashメッセージの設定
      session()->flash('success', 'メンバーを追加しました！');
 
      return redirect('/csv_sample');
 
    }

// ----コンバート用 関数----------------------------------------

      public function convertCsv(Request $request){

        $members_file = new \SplFileObject(storage_path('app/members.csv'));
        
        $convert_file = new \SplFileObject(storage_path('app/members_converted.csv'), 'w');
        
        $members_file->setFlags(
          \SplFileObject::READ_CSV | // CSVを配列形式で読み込む
          \SplFileObject::READ_AHEAD |
          \SplFileObject::SKIP_EMPTY | // 前の行と合わせて、空行があったら読み飛ばす
          \SplFileObject::DROP_NEW_LINE // 改行コードは無視する
        );
        
        $members = [];
        foreach($members_file as  $key => $member){
          $row = [$key] + $member;
            
          $members[] = $row;
        }

        foreach($members as $member){
          $convert_file -> fputcsv($member);
        }
        return redirect('/csv_sample');
      }
   }
```

※追記モードでSplFileObjectを作成するには、第２引数を 'a' に設定。
これは「append（追加）」の省略形である。



# ビュー

resources/views/samples/**csv_sample.blade.php**

```php
@extends('layouts.default')
 
@section('title', $title)
 
@section('content')
<h1>{{ $title }}</h1>
 
<form method="post">
  @csrf
  <div>
    <label>
      名前:
      <input type="text" name="user_name">
    </label>
  </div>
  <div>
    <label>
      住所:
      <input type="text" name="address">
    </label>
  </div>
  <div>
    <label>
      電話番号:
      <input type="text" name="phone">
    </label>
  </div>
  <div>
    <input type="submit" name="登録">
  </div>
</form>
 
@foreach($members as $member)
  <p>{{ $member[0] }}: {{ $member[1] }} TEL: {{ $member[2] }}</p>
@endforeach
 
 
<form method="post" action="{{ url('/convert_csv') }}">

   @csrf
    <input type="submit"  value = "コンバート">
 </form>
 
@endsection

```

### dd は「dump and die（データを吐いて終了）」の省略形。

# 共通レイアウトファイル

```PHP
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
    <style>
        .header_nav {
            display: flex;
            list-style: none;
            padding-left: 0;
        }
        .header_nav li {
            margin-right: 30px;
        }
        /* エラーメッセージ用のスタイル */
        .error {
          color: red;
        }
        /* 成功メッセージ用のスタイル */
        .success {
          color: green;
        }
    </style>
</head>
<body>
    @yield('header')
 
    {{-- エラーメッセージを出力 --}}
    @foreach($errors->all() as $error)
      <p class="error">{{ $error }}</p>
    @endforeach
 
    {{-- 成功メッセージを出力 --}}
    @if (session()->has('success'))
        <div class="success">
            {{ session()->get('success') }}
        </div>
    @endif
 
    @yield('content')
</body>
</html>
```

# 共通レイアウトファイル

```PHP
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
    <style>
        .header_nav {
            display: flex;
            list-style: none;
            padding-left: 0;
        }
        .header_nav li {
            margin-right: 30px;
        }
        /* エラーメッセージ用のスタイル */
        .error {
          color: red;
        }
        /* 成功メッセージ用のスタイル */
        .success {
          color: green;
        }
    </style>
</head>
<body>
    @yield('header')
 
    {{-- エラーメッセージを出力 --}}
    @foreach($errors->all() as $error)
      <p class="error">{{ $error }}</p>
    @endforeach
 
    {{-- 成功メッセージを出力 --}}
    @if (session()->has('success'))
        <div class="success">
            {{ session()->get('success') }}
        </div>
    @endif
 
    @yield('content')
</body>
</html>
```