Laravel8では7と比べ若干の仕様の違いで、今まで通りにコードを書くとエラーが発生します。 本記事では、Laravel8でのお問い合わせフォームの作成方法をまとめました。
作成ページ
- トップページ
- フォーム確認画面
- メール送信機能
- 送信完了ページ
これらを作成していきます。
開発環境
- Laravel8
ルーティングを作成
web.phpにルーティングを作成します。
トップページのルートから順を追って解説していきたいと思います。
routes/web.php
<?php use App\Http\Controllers\ContactController; //トップページ Route::get('/',[ContactController::class, 'index'])->name('index');
Controller内でurl('index')で遷移出来るようにname()もあらかじめ定義しています。 Laravel8ではControllerクラスをuseで呼び出す必要があります。
コントローラを作成
次にContactController.phpを作成していきます。
コマンドで'php artisan make controller ContactController'を実行します。
App\Http\Controllers\ContactController
<?php namespace App\Http\Controllers; class ContactController extends Controller { public function index() { return view('top'); } }
トップページを表示させるだけなので、非常にシンプルです。
トップページを作成
twigを作成します。
※入力項目部分のみ抜き出して記述しています。実際の開発では、他の箇所もそうですが、追加の項目やhtmlタグの追加などして見た目を整えて下さい。
resources/views/top.blade.php
<form method="POST" action="{{ route('confirm') }}" > @csrf @method('POST') <div class="form-inner"> <div class="form-cont"> <div class="mg-b_40"> <label for="name" class="required-tag">担当者名</label><br> <input type="text" placeholder="山田太郎" id="name" name="name" value="{{ old('name') }}"> @if($errors->has('name')) <p class="required">{{ $errors->first('name') }}</p> @endif </div> <div class="mg-b_40"> <label for="cname" class="required-tag">フリガナ</label><br> <input type="text" placeholder="ヤマダタロウ" id="cname" name="cname" value="{{ old('cname') }}"> @if($errors->has('cname')) <p class="required">{{ $errors->first('cname') }}</p> @endif </div> <div class="mg-b_40"> <label for="tel" class="required-tag">電話番号</label><br> <input type="tel" placeholder="0123456789" id="tel" name="tel" value="{{ old('tel') }}"> @if($errors->has('tel')) <p class="required">{{ $errors->first('tel') }}</p> @endif </div> <div class="mg-b_40"> <label for="email" class="required-tag lg-label">メールアドレス</label><br> <input type="email" placeholder="sample@example.com" id="mail" name="email" class="mg-b_10" value="{{ old('email') }}"> <input type="email" placeholder="確認のため再度入力してください" id="mail" name="email_confirmation"> @if($errors->has('email')) <p class="required">{{ $errors->first('email') }}</p> @endif @if($errors->has('email2')) <p class="required">{{ $errors->first('email2') }}</p> @endif </div> <div class="mg-b_40"> <label for="content" class="lg-label">お問い合わせ内容</label><br> <textarea name="content" id="content" cols="30" rows="10" placeholder="Message">{{ old('content') }}</textarea> </div> </div> </div>
route(confirm)でフォームの内容がrouteへ遷移するよう定義しています。 value="{{ old('name') }}"では、エラーが返った時に値は入力されたままになるように定義してます。 @if($errors->has('name'))…の部分では、エラーが返ってきたときに、エラー文を表示させるためです。
web.phpにconfirm を追加
routes/web.php
//確認ページ
Route::get('/confirm',[CotactController::class, 'confirm']);
Route::post('/confirm',[CotactController::class, 'confirm'])->name('confirm');
confirmメソッドをController内で作成
App\Http\Controllers\ContactController.php
//17: public function confirm(Request $request) { $inputs = $request->all(); if(!$inputs){ return redirect()->route('index'); } $request->validate([ 'name' => 'required', 'cname' => 'required', 'tel' => ['required', 'numeric', 'digits_between:8,11'], 'email' => ['required','email','confirmed'], 'messgae' => 'max:4000' ]); return view('confirm',[ 'inputs' => $inputs, ]); }
20行目から解説すると、postで渡されたdataを$request->all()で取得して$inputsの格納しています。22行目で、もし$inputsに値が格納されていなければ、indexにリダイレクトさせます。例えば、直接、confirmのurlにアクセスされた場合があるのでこのような記述をしています。 26行目からそれぞれの項目にバリデーションを行っています。 もしバリデーションに引っかかった場合は、エラーを返します。
confirmページを作成
resources/view/confirm.blade.php
<form method="POST" action="{{ route('send') }}" class="confirm__ar"> {{ csrf_field() }} {{ method_field('POST') }} <dt class="confirm__tag">担当者名</dt> <dd>{{ $inputs['name'] }}</dd> <input type="hidden" name="name" value="{{ $inputs['name'] }}"> </dl> <dl> <dt class="confirm__tag">フリガナ</dt> <dd>{{ $inputs['cname'] }}</dd> <input type="hidden" name="cname" value="{{ $inputs['cname'] }}"> </dl> <dl> <dt class="confirm__tag">電話番号</dt> <dd>{{ $inputs['tel'] }}</dd> <input type="hidden" name="tel" value="{{ $inputs['tel'] }}"> </dl> <dl> <dt class="confirm__tag">メールアドレス</dt> <dd>{{ $inputs['email'] }}</dd> <input type="hidden" name="email" value="{{ $inputs['email'] }}"> </dl> <dl> <dt class="confirm__tag">お問い合わせ内容</dt> <dd> {!! nl2br(e($inputs['content'])) !!} <input type="hidden" name="content" value="{{ $inputs['content'] }}"> </dd> </dl> <div class="confirm_bk"> <a href="{{ route('index') }}" class="back_btn"><span class="f-bold">戻る</span></a> <input onclick="submit();" type="button" value="この内容で送信する" class="confirm_btn"> </div> </form>
formの部分のみ抜き出して記載しています。 それぞれの値を$input[name名]で呼び出して表示させてます。 inputタグでは、typeをhiddenにして表側では表示させずに、submitで入力の値を渡しています。routeは('send')を指定しているので、送信ボタンを押すとname('send')を通ります。
メール送信行うためのrouteを記述
//送信完了ページ
Route::get('/thanks',[CotactController::class, 'send']);
Route::post('/thanks',[ContactController::class, 'send'])->name('send');
Controllerにsendメソッドを作成
public function send(Request $request) { $inputs = $request->all(); if(!$inputs){ return redirect()->route('index'); } \Mail::to($inputs['email'])->send(new ContactSendMail($inputs); $request->session()->regenerateToken(); //2回メール送信を防ぐため return view('thanks'); }
最初の部分はconfirmと同じく、$inputsに全値を格納します。inputsに値が格納されていない場合は、トップページへリダイレクトします。
\Mailとあるのは、Laravelが提供しているメールを送信する為に必要なMailファサードです。\Mailで呼び出すことができます。因みに\Mailで呼び出すことができるのは、 configのディレクトリ内のapp.phpに274行目あたりに'Mail' => Illuminate\Support\Facades\Mail::class,とエイリアスが定義されているからです。 先ずは、to() の中に宛先のメールをアドレスを記述します。 フォームで入力されているアドレスを$input['email'] で取得します。 メールの内容は、Mailableクラスを使用します。 Controllerの5行目あたりにContactSendMailを使用できるようにuseを記述します。
use App\Mail\ContactSendMail;
ContacdtSendMail.phpを作成
php artisan make:mail ContacdtSendMailとコマンドを実行します。 app/Http/MailにContactSendMail.phpのファイルが作成されいるので、内容を下記のように変更します。
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class ContactSendMail extends Mailable { use Queueable, SerializesModels; private $name; private $cname; private $tel; private $emal; private $message; /** * Create a new message instance. * * @return void */ public function __construct($inputs,$type) { $this->name = $inputs['name']; $this->cname = $inputs['cname']; $this->tel = $inputs['tel']; $this->email = $inputs['email']; $this->content = $inputs['content']; } /** * Build the message. * * @return $this */ public function build() { return $this ->subject('お問い合わせありがとうございます') ->view('emails.urer') ->with([ 'name' => $this->name, 'cname' => $this->cname, 'tel' => $this->tel, 'email' => $this->email, 'content' => $this->content ? $this->content : null ]); } }
$inputsに格納されている値をwith()で配列として値を渡します。
メールの内容をbladeで作成
resources/emails/user.blade.php
【このメールはシステムからの自動返信です。】<br> <br> <br> {{ $name }} 様<br> <br> この度は、お問い合わせいただき、誠にありがとう御座います。<br> お送り頂いた内容を確認の上、担当者より折り返しご連絡させていただきます。<br> <br> 担当者名: {{ $name }}<br> フリガナ: {{ $cname }}<br> 電話番号: {{ $tel }}<br> メールアドレス: {{ $email }}<br> お問い合わせ内容:<br> {!! nl2br($content) !!}<br> <br>
非常にシンプルですが、基本的な内容のメール文です。
最後にメール送信が完了したあとに送信完了ページを resources/emails/thanks.blade.phpで作成したら一連の流れは完了です。
以上となります。 途中でも説明もしていますが、CSSやhtmlタグやフォームの項目などは必要用途に応じて整えてください。
Have a development day!!