こんにちは、ryohei(@ityryohei)です。

本記事は「Laravel5.8」で確認画面付きのお問い合わせフォームを作成する方法のご紹介になります。

内容としては、入力ページ→入力内容確認ページ→送信完了ページの3ステップ構成のお問い合わせフォームになります。DBに保存する形式ではなく、自動返信メールを送信するだけの処理です。

お問い合わせフォームはユーザーからバグの報告や改善してほしい点などの情報もいただけるので、Webアプリケーションには必須の機能になります。Laravelではメールの送信処理を簡単に実装することができますので、お問い合わせフォームを構築しながら解説していきたいと思います。

注意事項

  • 本記事ではルーティング→コントローラー→ビューの順で構築する方法をご紹介しています。エンジニアによって構築方法は異なると思いますので、構築しやすい順番で進めていただければと思います。また、本記事ではLaravelをインストールが完了していることを前提に解説していきます。予めご了承ください。
  • 本記事ではBootstrapを使用しておりません。また、レイアウトファイルの説明も割愛しております。お問い合わせフォームが完成した後にデザインをしていただければと思います。

では、解説していきます。

.envでメールの設定をする

まずはメールの送信ができるように「.env」編集します。「.env」ファイルはプロジェクトの直下にあります。(もしファイルが見えない場合は隠しファイルが表示されない設定なっている可能性がありますので、隠しファイルが表示されるようにOSやエディタを設定しましょう。)

.env」のメールの設定は下記の部分になります。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465 (587)
MAIL_USERNAME=YOUR_USERNAME
MAIL_PASSWORD=YOUR_PASSWORD
MAIL_ENCRYPTION=ssl (tls)
MAIL_FROM_ADDRESS=YOUR_ADDRESS
MAIL_FROM_NAME=YOUR_NAME

サンプルではGmailをホストに設定していますが、こちらにはご自身が使用しているメールアドレスのホストを指定してください。もしGmailを使用される場合は、そのままアカウント情報を入力していただければ大丈夫です。(その際は、Googleアカウントの設定から「安全性の低いアプリからのアカウントへのアクセスを許可する」を有効にする必要があります。)

以上でメールの設定は完了です。続いてルーティングを設定していきます。

ルーティングを作成する

メール設定が終わったら、最初にページにアクセスするためのルーティングを決めていきます。本記事では下記のようにルーティングしています。

route

[操作ファイル] route/web.php


<?php

//入力ページ
Route::get('/contact', 'ContactController@index')->name('contact.index');

//確認ページ
Route::post('/contact/confirm', 'ContactController@confirm')->name('contact.confirm');

//送信完了ページ
Route::post('/contact/thanks', 'ContactController@send')->name('contact.send');

コマンドプロンプトやターミナルでphp artisan serveを実行した状態であれば、下記のURLでアクセスするイメージになります。(現時点では表示されません。)

//入力ページ
http://127.0.0.1:8000/contact

//確認ページ
http://127.0.0.1:8000/contact/confirm

//送信完了ページ
http://127.0.0.1:8000/contact/thanks

以上でルーティングは完了です。続いてコントローラーを作成していきます。

コントローラーを作成する

ルーティングが決まりましたので、次はコントローラーを作成します。Windowsであればコマンドプロンプトかパワーシェル、Macであればターミナルを起動して下記のコマンドを実行します。

php artisan make:controller ContactController

コマンドを実行すると「app/Http/Controllers」の配下にファイルが作成されます。「ContactController.php」を開いてメソッドを追記します。

ContactController

[操作ファイル]app/Http/Controllers/ContactController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function index()
    {
    }

    public function confirm(Request $request)
    {
    }

    public function send(Request $request)
    {
    }
}

各メソッドの処理につきましてはいったん空のままで大丈夫です。一ページずつ解説しながら処理を追記していきます。

各ページのビューを作成する

ルーティングとコントローラーが作成できましたので、続いてWebページの表示部分にあたるビューを作成します。resources/viewsの配下にcontactのディレクトリを作成して、配下にbladeファイルを作成します。コマンドではなくOSやエディタの機能で新規ファイルを作成します。

//入力ページ
resources/views/contact/index.blade.php

//確認ページ
resources/views/contact/confirm.blade.php

//送信完了ページ
resources/views/contact/thanks.blade.php

ここまででルーティングとコントローラー、ビューの基本的なファイルの作成が完了しました。これから各ページにコードを追記していきます。少し難しい部分になりますが、焦らずにゆっくりコードを追っていただければと思います。

フォーム入力画面を作成する

まずはフォームの肝となる入力画面から。

作成したコントローラーのメソッドに処理を追記します。

ContactController

[操作ファイル] app/Http/Controllers/ContactController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function index()
    {
        //フォーム入力画ページのviewを表示
        return view('contact.index');
    }


    public function confirm(Request $request)
    {
    }

    public function send(Request $request)
    {
    }
}

route/web.php」には下記のようにルーティングしました。

//入力ページ
Route::get('/contact', 'ContactController@index')->name('contact.index');

この意味合いとしては、「/contact」にGETリクエストのアクセスがあったら「ContactController」の「index()」メソッドが呼び出される、といった内容になります。nameに指定しているcontact.index」は、ルーティングに名前を付ける、という解釈です。この辺をしっかり理解しておくことで、全体の理解が深まるかと思います。

続いビューの編集に移ります。上で作成した「contact/index.blade.php」に下記を追記します。

index.blade

[操作ファイル] resources/views/contact/index.blade.php


@extends('layout')
 
@section('content')
<form method="POST" action="{{ route('contact.confirm') }}">
    @csrf

    <label>メールアドレス</label>
    <input
        name="email"
        value="{{ old('email') }}"
        type="text">
    @if ($errors->has('email'))
        <p class="error-message">{{ $errors->first('email') }}</p>
    @endif

    <label>タイトル</label>
    <input
        name="title"
        value="{{ old('title') }}"
        type="text">
    @if ($errors->has('title'))
        <p class="error-message">{{ $errors->first('title') }}</p>
    @endif


    <label>お問い合わせ内容</label>
    <textarea name="body">{{ old('body') }}</textarea>
    @if ($errors->has('body'))
        <p class="error-message">{{ $errors->first('body') }}</p>
    @endif

    <button type="submit">
        入力内容確認
    </button>
</form>
@endsection

一般的なフォームとエラーメッセージの出力処理を記述しています。@csrfはCSRFのトークンを生成してくれます。

以上でフォーム入力画面を作成は完了です。続いて入力内容確認ページを作成していきます。

入力内容確認ページを作成する

フォーム入力と同じように、確認ページに処理を追記していきます。

まずはコントローラーから。

ContactController

[操作ファイル] app/Http/Controllers/ContactController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function index()
    {
        //フォーム入力画ページのviewを表示
        return view('contact.index');
    }

    public function confirm(Request $request)
    {
        //バリデーションを実行(結果に問題があれば処理を中断してエラーを返す)
        $request->validate([
            'email' => 'required|email',
            'title' => 'required',
            'body'  => 'required',
        ]);
        
        //フォームから受け取ったすべてのinputの値を取得
        $inputs = $request->all();

        //入力内容確認ページのviewに変数を渡して表示
        return view('contact.confirm', [
            'inputs' => $inputs,
        ]);
    }

    public function send(Request $request)
    {
    }
}

続いて作成した「contact/confirm.blade.php」に追記します。

confirm.blade

[操作ファイル] resources/views/contact/confirm.blade.php


@extends('layout')

@section('content')
<form method="POST" action="{{ route('contact.send') }}">
    @csrf

    <label>メールアドレス</label>
    {{ $inputs['email'] }}
    <input
        name="email"
        value="{{ $inputs['email'] }}"
        type="hidden">

    <label>タイトル</label>
    {{ $inputs['title'] }}
    <input
        name="title"
        value="{{ $inputs['title'] }}"
        type="hidden">


    <label>お問い合わせ内容</label>
    {!! nl2br(e($inputs['body'])) !!}
    <input
        name="body"
        value="{{ $inputs['body'] }}"
        type="hidden">

    <button type="submit" name="action" value="back">
        入力内容修正
    </button>
    <button type="submit" name="action" value="submit">
        送信する
    </button>
</form>
@endsection

以上で入力内容確認ページを作成は完了です。

次は送信完了ページ、といきたいところですが、先にメールを送信するのに必要なMailableクラスを作成しておきます。

メール送信処理を実装する

ではメール送信処理を実装していきます。

Mailableクラスを作成する

下記のコマンドをコマンドプロンプトもしくはターミナルで実行します。

php artisan make:mail ContactSendmail

app/Mail/ContactSendmail.php」に新しいファイルが作成されます。こちらを修正していきます。

ContactSendmail

[操作ファイル] app/Mail/ContactSendmail.php


<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ContactSendmail extends Mailable
{
    use Queueable, SerializesModels;

    private $email;
    private $title;
    private $body;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct( $inputs )
    {
        $this->email = $inputs['email'];
        $this->title = $inputs['title'];
        $this->body  = $inputs['body'];
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this
            ->from('advan.ryohei@gmail.com')
            ->subject('自動送信メール')
            ->view('contact.mail')
            ->with([
                'email' => $this->email,
                'title' => $this->title,
                'body'  => $this->body,
            ]);
    }
}

メールテンプレートも一緒に作成しておきます。

メールテンプレートを作成する

resources/views/contact」の配下に下記のファイルを作成して、メール本文を追記します。

mail.blade

[操作ファイル] resources/views/contact/mail.blade.php


お問い合わせ内容を受け付けました。<br>
<br>
■メールアドレス<br>
{!! $email !!}<br>
<br>
■タイトル<br>
{!! $title !!}<br>
<br>
■お問い合わせ内容<br>
{!! nl2br($body) !!}<br>

以上でメール送信処理の実装は完了です。

最後に送信完了ページを作成します。

送信完了ページを作成する

まずはコントローラーから。

ContactController

[操作ファイル] app/Http/Controllers/ContactController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Mail\ContactSendmail;

class ContactController extends Controller
{
    public function index()
    {
        //フォーム入力画ページのviewを表示
        return view('contact.index');
    }

    public function confirm(Request $request)
    {
        //バリデーションを実行(結果に問題があれば処理を中断してエラーを返す)
        $request->validate([
            'email' => 'required|email',
            'title' => 'required',
            'body'  => 'required',
        ]);
        
        //フォームから受け取ったすべてのinputの値を取得
        $inputs = $request->all();

        //入力内容確認ページのviewに変数を渡して表示
        return view('contact.confirm', [
            'inputs' => $inputs,
        ]);
    }

    public function send(Request $request)
    {
        //バリデーションを実行(結果に問題があれば処理を中断してエラーを返す)
        $request->validate([
            'email' => 'required|email',
            'title' => 'required',
            'body'  => 'required'
        ]);

        //フォームから受け取ったactionの値を取得
        $action = $request->input('action');
        
        //フォームから受け取ったactionを除いたinputの値を取得
        $inputs = $request->except('action');

        //actionの値で分岐
        if($action !== 'submit'){
            return redirect()
                ->route('contact.index')
                ->withInput($inputs);

        } else {
            //入力されたメールアドレスにメールを送信
            \Mail::to($inputs['email'])->send(new ContactSendmail($inputs));

            //再送信を防ぐためにトークンを再発行
            $request->session()->regenerateToken();

            //送信完了ページのviewを表示
            return view('contact.thanks');
            
        }
    }
}

ビューも簡単に追記します。

thanks.blade

[操作ファイル] resources/views/contact/thanks.blade.php


@extends('layout')

@section('content')
<h1>{{ __('送信完了') }}</h1>
@endsection

以上でLaravelを使ったお問い合わせフォームの完成になります。

最後に

いかがでしたでしょうか。

Laravelでは、お問い合わせフォームを短時間で構築することができます。バリデーションチェックやトークンの作成も少ない記述で実装することができる点もLaravelの魅力ですよね。今後もLaravel関連の投稿を続けていきたいと思います。

以上、Laravelで確認画面付きのお問い合わせフォームを作成する方法のご紹介でした!