Laravel5でフォームを作る方法

Laravel5でフォームを作ってみます。
機能としては、フォームから取り込んだ情報をDBに格納、メール送信辺りになります。

まずはDBを周りを作って、マイグレーションファイルの作成・実行、そのあとコントローラーとビュー周りをやります。

 

入力項目に応じてDBの項目を考えていきます。Laravelはある程度必要なものはartisanコマンドで揃えられるのでいいですね。

テーブル名は「ContactUser」とします。項目は以下の通り。

カラム名
データ型
内容
id
increments
ID
last_name
string (32)
姓*
first_name
string (32)
名*
last_name_kana
string (64)
セイ
first_name_kana
string (64)
メイ
company
string (128)
会社名 団体名
email
string (email)
Email*
category
string (64)
カテゴリー
message
text
質問内容*
remark
text
備考 (管理者記入)
deleted_at
softDeletes(delFlag)
削除フラグ
created_at
timestamps
作成日
updated_at
timestamps
更新日

 

大体こんなもんで大丈夫でしょう。

名前やメールアドレス、質問内容は必須項目にしておきます。他にも必須項目にしたいものがあったらやっておきましょう。

マイグレーションの作成

テーブルを作っていきますが、Laravelならマイグレーションを使った方が便利です。

artisanコマンドでid,timestamps(created_at,updated_at)が自動的に作成されます。その他の項目は自力で追加していきましょう。モデルも一緒に作ってしまいます。

$ php artisan make:model ContactUser --migration
Model created successfully.
Created Migration: 2017_05_06_130517_create_contact_users_table

これでモデルとマイグレーションファイルは作成できました。

modelは、「app/ContactUser.php」

migrationは、「database/migrations/yyyy_mm_dd_hhiiss_create_contact_users_table.php」
に作成されているはずです。

migrationファイルは自動的に指定したテーブル名の複数形になっています。

次にテーブルを作成してしまいます。

テーブル作成のコマンドは以下の通り。これをマイグレーションファイルに追加してください。

$table->increments('id');
$table->string('last_name', 32);
$table->string('first_name', 32);
$table->string('last_name_kana', 64);
$table->string('first_name_kana', 64);
$table->string('company', 64);
$table->string('email');
$table->string('category', 64);
$table->text('message');
$table->text('remark');
$table->softDeletes('delFlag');
$table->timestamps();

 

次に以下のコマンドでテーブルを作成。

php artisan migrate

 

これだけでテーブルが作れます。万が一失敗しても、ロールバックは何度でもできるので安心してください。

もし何らかのエラーでテーブルが作れない場合はDB接続がうまくいっていない可能性があります。設定とか接続とか見直してみてください。

また、指定したテーブルだけ作成したい場合は以下のコマンドのように明示的にテーブル名を指定しても大丈夫です。

php artisan make:migration ContactUsers

 

これでテーブルの作成ができました。

ちなみにこのテーブル作成の時にmigrationsというテーブルが自動的に作成され、その履歴が記録されています。

コントローラーとビューを作成

フォームからPOSTでデータを送れるようにコントローラーとビューを作成します。

アクセスURLは簡単に

/contactus/index
/contactus/confirm
/contactus/complete

 

こんな感じでいいと思います。

POSTを受け取る部分と保存する部分があれば最低限大丈夫ですが、今回はURLを3つに分けて作ってみました。

そうしたら、これらに対応するルーティングとコントローラメソッド、ビューを作成していきます。

// routes/web.php
....
// contact us
Route::get('/contactus/index', 'ContactsController@index');
Route::match(['get', 'post'],'/contactus/confirm', 'ContactsController@confirm');
Route::get('/contactus/complete', 'ContactsController@complete');
....

 

簡単に説明すると、indexはフォームのパーツを表示、confirmでPOSTを受け取って確認、complateで受け取った値を保存したり、メール送信処理を行ったりします。

コントローラーの作成

コントローラーは雛形とartisanでサクッと作ってしまいましょう。

php artisan make:controller ContactsController

 

この時、コントローラーは複数形で作るようにしてください。単数形だとコマンドで作成できないからです。

作ったからのコントローラーの中に対応するメソッドを追加していきます。

 // app/Http/Controllers/ContactsController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactsController extends Controller
{
//
}

 

テンプレートをまだ作成していないので、ここではreturnで文字列だけ返してあげるようにしておきます。
ルーティングとコントローラが接続できていれば大丈夫です。

 }

public function index()
{
return 'index';
}

public function confirm()
{
return 'confirm';
}

public function complete()
{
return 'complete';
}
}

 

テンプレートの作成

Bladeを使ってテンプレートを作っていきます。拡張子が「.blade.php」のアレですね。

今回はビューのテンプレートを

resources/views/contact/index.blade.php
resources/views/contact/confirm.blade.php
resources/views/contact/complete.blade.php

 

という感じに作成します。

なお、LaravelにはCSRF対策のトークンがデフォルト機能で備わっているので、隠し項目にその内容を追加するだけでトークンが有効かどうかを内部的に自動で判定してくれます。

(今回はエラーが出た場合の対処は省略)

<form action="/contactus/confirm" id="" name="" class="" method="post">
    <div>
        <label for="last_name">姓</label><input type="text" id="last_name" name="last_name">
        <label for="first_name">名</label><input type="text" id="first_name" name="first_name">
    </div>
    <div>
        <label for="last_name_kana">セイ</label><input type="text" id="last_name_kana" name="last_name_kana">
        <label for="first_name_kana">メイ</label><input type="text" id="first_name_kana" name="first_name_kana">
    </div>
    <div>
        <label for="company">会社名</label><input type="text" id="company" name="company">
    </div>
    <div>
        <label for="email">Email</label><input type="text" id="email" name="email">
    </div>
    <div>
        <label for="chk1">ご意見・ご要望</label><input type="checkbox" name="chk1" id="chk1" value="ご意見・ご要望" checked>
        <label for="chk2">質問・お問い合わせ</label><input type="checkbox" name="chk2" id="chk2" value="質問・お問い合わせ">
        <label for="chk3">その他</label><input type="checkbox" name="chk3" id="chk3" value="その他">
    </div>
    <div>
        <label for="message"></label>
        <textarea id="message" name="message"></textarea>
    </div>
    <div>
        <input type="hidden" name="_token" value="{{csrf_token()}}">
        <input type="submit" id="submit" name="submit" value="送信">
    </div>
</form>

そしたらビューとコントローラーを結びつけます。

先ほどコントローラーを作った際はとりあえず文字列を返すようにしていましたが、それは消してそれぞれのテンプレートのパスを指定してあげます。

return view('contact/index');
return view('contact/confirm');
return view('contact/complete');

 

これで/contactus/indexなどにアクセスするとそれぞれのページを表示できるようになりました。

confirmでPOSTデータを受け取る

フォームから送信されたPOSTはいろいろな方法で受け取ることができますが、ここでは、Dependency Injection (DI)を使って処理してみます。

先にコントローラに、Illuminate\Http\Requestを追加してconfirmメソッドの引数でリクエストを受けられるようにしておくようにしましょう。

Illuminate\Support\Facades\DBも後々使うので同時に追加しておいても大丈夫です。

 return view('contact/confirm');
}

public function complete()
{
return view('contact/complete');
}
}

$request->all()はおすすめ出来ないので、個別に受け取れるように、nameの値を引数にとってあげましょう。

$request->input('last_name');
$request->input('first_name');
$request->input('last_name_kana');
$request->input('first_name_kana');
$request->input('company');
$request->input('email');
$request->input('chk1');
$request->input('chk2');
$request->input('chk3');
$request->input('message');
$request->input('_token');
$request->input('submit'));

 

POSTのデータが正しい値であるかはバリデーション処理が必要ですが、LaravelではApp\Http\Controllers\Controllerクラスの中でValidatesRequestsトレイトが常に呼び出されているのでコントローラ内でいつでも使えます。

つまり、コイツが自動的にバリデーション処理をしてくれるので、わざわざバリデーション処理を自分で行う必要はありません。

public function confirm(Request $request)
{
// do to validate
$this->validate($request, [
'last_name' => 'required|max:16',
'first_name' => 'required|max:16',
'email' => 'required|email',
'message' => 'required|max:1200',
]);
....
// 確認画面の処理

 

この辺はちゃんと考えるとかなり面倒というか設計思想が必要になってくるので、ここでは単に必須項目とmaxlengthを指定して、エラーになったらPOSTできないという感じで終わらせます。

とりあえずこれでPOSTの受け取りはOK。

POSTの値をセッションに格納する

確認画面(confirm)から完了画面(complate)の移動の際にはPOSTを使う必要は特にないので、セッションに入れておきます。

セッションはリクエストのインスタンスを経由して保持しておきます。

$request->session()->put('last_name', $request->input('last_name'));
$request->session()->put('first_name', $request->input('first_name'));
$request->session()->put('last_name_kana', $request->input('last_name_kana'));
$request->session()->put('first_name_kana', $request->input('first_name_kana'));
$request->session()->put('company', $request->input('company'));
$request->session()->put('email', $request->input('email'));
$request->session()->put('email', $request->input('chk1'));
$request->session()->put('email', $request->input('chk2'));
$request->session()->put('chk3', $request->input('chk3'));
$request->session()->put('message', $request->input('message'));
$request->session()->put('_token', $request->input('_token'));
$request->session()->put('submit', $request->input('submit'));

 

そしたらconfirmのテンプレートに値を送ります。

compact関数でもwithメソッドでもどちらでもいいですが、今回はwithメソッドを使って送ってみます。

return view('contact/confirm')
->with( [
'last_name'=> $request->session()->get('last_name'),
'first_name'=> $request->session()->get('first_name'),
'last_name_kana'=> $request->session()->get('last_name_kana'),
'first_name_kana'=> $request->session()->get('first_name_kana'),
'company'=> $request->session()->get('company'),
'email'=> $request->session()->get('email'),
'chk1'=> $request->session()->get('chk1'),
'chk2'=> $request->session()->get('chk2'),
'chk3'=> $request->session()->get('chk3'),
'message'=> $request->session()->get('message'),
]);

 

withメソッドで複数の値を渡す際は連想配列にします。

bladeではkeyをblade独特の変数にすると取得できます。

完了画面への遷移はアンカーで足りるので、リンクを作って済ませます。

{{$last_name}}<br>
{{$first_name}}<br>
{{$last_name_kana}}<br>
{{$first_name_kana}}<br>
{{$company}}<br>
{{$email}}<br>
{{$chk1}}<br>
{{$chk2}}<br>
{{$chk3}}<br>
{{$message}}<br>
<br>
<a href="/contactus/complete">送信</a>

 

送信をクリックすると完了画面に遷移してデータが送られるという感じです。

DBへ保存・メール送信処理

DBに格納する際は先ほどセッションに保存した値を取り出せばOKです。最後にDBに保存して、メールを送信すればOKですね。

先ほどリクエストのインスタンス経由でセッションに保存したので、complateメソッドの引数にリクエストを渡します。

セッションを取り出すのはこんな感じでやれば大丈夫です。

public function complete(Request $request)
{
// Session
var_dump($request->session()->get('last_name'));
var_dump($request->session()->get('first_name'));
var_dump($request->session()->get('last_name_kana'));
var_dump($request->session()->get('first_name_kana'));
var_dump($request->session()->get('company'));
var_dump($request->session()->get('email'));
var_dump($request->session()->get('chk1'));
var_dump($request->session()->get('chk2'));
var_dump($request->session()->get('chk3'));
var_dump($request->session()->get('message'));
var_dump($request->session()->get('_token'));
var_dump($request->session()->get('submit'));

return view('contact/complete');
}

 

次にテーブルにインサートしますが、DBに格納するためにはモデルとコントローラの関連付けとEloquentを利用します。

DBを扱うには、Illuminate\Support\Facades\DBをuseすればOKです。それからモデルを呼び出します。

use Illuminate\Support\Facades\DB;
use App\ContactUser;

 

あとはモデルが取得したオブジェクトに更新情報をあたえてsave()するだけ。

$contact = new ContactUser;
var_dump($contact);
$contact->last_name = $request->session()->get('last_name');
$contact->first_name = $request->session()->get('first_name');
var_dump($contact->last_name);
$contact->save();

 

こんな感じでできれば問題ないでしょう。

今回はこれで以上です。