PHPフレームワークLaravel5.6でCRUD~CREATE編

CREATEは新規登録機能なのでcreateメソッドで登録フォームを作ってstoreメソッドで保存。

入力項目は
タイトル:text
カテゴリ:select
説明:textarea
だけ。

コントローラーにcreateメソッド追加

app/Http/Controllers/TestController.php

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{

    const CATEGORY_LIST = [1 => 'カテゴリ1', 2 => 'カテゴリ2', 3 => 'カテゴリ3', 4 => 'カテゴリ4', 5 => 'カテゴリ5'];

    [・・・省略・・・]

    public function create()
    {
        $data = [];
        $data['categories'] = self::CATEGORY_LIST;
        return view('test/create', $data);
    }

}

カテゴリは何度も使うので定数定義しておく。

※PHP5.6からconstに配列も使えるようになった!

入力ページ(View)を作るよ

resources/views/test/create.blade.php

@extends('layouts.app')

@section('content')
<div class="container">

  <div class="panel panel-default">

    <h2>新規追加</h2>
    <a href="/test"><button class="btn btn-primary">一覧に戻る</button></a>

    <form action="/test" method="POST">
      @csrf
      <div class="form-group">
        <label>タイトル</label>
        <input type="text" name="title" value="{{ old('title')}}" class="form-control">
        @if($errors->has('title'))
        <span class="text-danger">{{ $errors->first('title') }}</span>
        @endif
      </div>
      <div class="form-group">
        <label>カテゴリ</label>
        <select name="category" class="form-control">
          <option value="">選択してください</option>
        @foreach ($categories as $key => $category)
          <option value="{{ $key }}"@if($key == old('category')) selected @endif>{{ $category }}</option>
        @endforeach
        </select>
        @if($errors->has('category'))
        <span class="text-danger">{{ $errors->first('category') }}</span>
        @endif
      </div>
      <div class="form-group">
        <label>説明</label>
        <textarea name="description" class="form-control">{{ old('description')}}</textarea>
        @if($errors->has('description'))
        <span class="text-danger">{{ $errors->first('description') }}</span>
        @endif
      </div>
      <button type="submit" class="btn btn-primary">登録</button>
    </form>

  </div>

</div>
@endsection

※Resourcefulルーティングだとformのmethodプロパティが「POST」ならactionプロパティは「/test」だけでstoreメソッドを呼び出す。
※@csrfはCSRF(クロスサイトリクエストフォージェリ)対策のトークンを生成。

/test/createにアクセスして確かめよう

コントローラーにstoreメソッド追加

app/Http/Controllers/TestController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
// Testモデルをインポート
use App\Models\Test;

class TestController extends Controller
{

    [・・・省略・・・]

    public function store(Request $request)
    {
        // POSTデータ
        $post = $request->all();
        // Testモデルのインスタンス
        $test = new Test();
        // POSTデータの配列から登録できるカラムを抽出->INSERT
        $test->fill($post)->save();
        return redirect('test');
    }

}

※Testモデルを使用するのでuse文でインポート!
このクラスで「Test」と言えばTestモデルのこと。

※fillメソッドは引数の配列でモデルのプロパティを設定してくれる!
どんなプロパティがあるかわからないと設定できないからインスタンス化しないと設定できない。

バリデーションを追加

【コントローラー側】

TestController.phpのstoreメソッドに追加します。

app/Http/Controllers/TestController.php

    public function store(Request $request)
    {
        // バリデーション
        $this->validate($request, 
            [
                'title' => 'required',
                'category' => 'required',
                'description' => 'required',
            ],
            [
//                'title.required' => 'タイトルを入力してください',
                'category.required' => 'カテゴリを選択してください',
//                'description.required' => '説明を入力してください',
            ],
            [
//                'title' => 'タイトル',
//                'category' => 'カテゴリ',
                'description' => '説明',
            ]
        );

        // POSTデータ
        $post = $request->all();
        // Testモデルのインスタンス
        $test = new Test();
        // POSTデータの配列から登録できるカラムを抽出->INSERT
        $result = $test->fill($post)->save();
        return redirect('test');
    }

validateメソッドの引数は4つ。
①Request $request :リクエスト
②array $rules :ルール
③array $messages = [] :メッセージ
④array $customAttributes = [] :カスタム属性

・メッセージそのものを変えたいときは第3引数の$messageに[リクエストのキー].[ルール]に対応するメッセージを設定すればOK。
・第4引数$customAttributesを設定しない場合はリクエストのキーが使用される。

コメントアウトを外して確かめよう!

◎バリデーションの設定しかしてないけどエラー時には自動リダイレクトされる!すばらしい!

【ビュー側】

resources/views/test/create.blade.php

@extends('layouts.app')

@section('content')
<div class="container">

  <div class="panel panel-default">

    <h2 class="text-white bg-secondary">新規追加</h2>
    <a href="/test"><button class="btn btn-primary">一覧に戻る</button></a>

    <form action="/test" method="POST">
      @csrf
      <div class="form-group">
        <label>タイトル</label>
        <input type="text" name="title" value="{{ old('title')}}" class="form-control">
        @if($errors->has('title'))
        <span class="text-danger">{{ $errors->first('title') }}</span>
        @endif
      </div>
      <div class="form-group">
        <label>カテゴリ</label>
        <select name="category" class="form-control">
          <option value="">選択してください</option>
        @foreach ($categories as $key => $category)
          <option value="{{ $key }}"@if($key == old('category')) selected @endif>{{ $category }}</option>
        @endforeach
        </select>
        @if($errors->has('category'))
        <span class="text-danger">{{ $errors->first('category') }}</span>
        @endif
      </div>
      <div class="form-group">
        <label>説明</label>
        <textarea name="description" class="form-control">{{ old('description')}}</textarea>
        @if($errors->has('description'))
        <span class="text-danger">{{ $errors->first('description') }}</span>
        @endif
      </div>
      <button type="submit" class="btn btn-primary">登録</button>
    </form>

  </div>

</div>
@endsection

・old(‘[input:name属性]’)で前回入力された値を取得できる。
・$errors->has(‘[input:name属性]’)でバリデーションエラーの有無が判別できる。
・バリデーションの各エラーは$errors->first(‘[input:name属性]’)で取得できる。

★コントローラーでビューへ渡す変数に「errors」使えないね。φ(・_・”)メモメモ