- 投稿日:2021-01-20T19:52:36+09:00
【Laravel】Mailableを使ってメールを送信する方法。データや画像を添付する方法や入力データをメール本文に渡す方法
Mailableを使ってメールを送信する方法について。
【Laravel】Localhostでgmailを使ってメールを送信する方法。Mailableを使わない方法と使う方法の続きです。
基本的な設定や各記述の意味は上記リンク参照。
目次
- .envの設定
- Mailableクラスの作成
- コントローラの作成
- ルーティングの作成
- コンタクトフォームの作成(view)
- メール内容の作成(view)
- サーバーを起動とメール送信処理の実行
- メールにデータを添付する方法
- メール本文に画像を埋め込む方法
- メール本文にデータを渡す方法
1. .envの設定
Gmailを送信元のメールサーバーとして使うため、環境変数の設定が必須。
ルートディレクトリ直下の.envの下記部分に追記する。
デフォルトMAIL_MAILER=smtp MAIL_HOST=mailhog MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}"↓
変更後MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com //gmailを指定 MAIL_PORT=587 //メッセージ送信のポート(465ではない) MAIL_USERNAME=xxxx@gmail.com //gmailアドレス MAIL_PASSWORD=xxxxxxxxxxxxxxxx //16桁のPW MAIL_ENCRYPTION=tls //tls通信 #MAIL_FROM_ADDRESS=null //gmailの場合不要 MAIL_FROM_NAME="送信者の名前" //メールの送信者に表示される名前
2. Mailableクラスの作成
・
php artisan make:mail [Mailableクラス名]
▼実例
$ php artisan make:mail ContactReply Mail created successfully.▼ファイルを編集
ContactReply.php(編集後)<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class ContactReply extends Mailable { use Queueable, SerializesModels; /** * Create a new message instance. * * @return void */ public function __construct() { // } /** * Build the message. * * @return $this */ public function build() { //以下追記 return $this->view('emails.text') ->subject('メールの標題'); } }中にある関数は、
__construct
とbuild
の2つのみ。
今回は、build関数にメール本文の処理を記述。宛先はコントローラに記述する。
・Illuminate\Bus\Queueable
キュー関連のメソッド(接続指定など)をもつクラス。・
Illuminate\Contracts\Queue\ShouldQueue
非同期で実行するため、ジョブをキューへ投入することをLaravelへ知らせるクラス。・
Illuminate\Mail\Mailable
メール送信処理を指定するメソッドを持つクラス。・
Illuminate\Queue\SerializesModels
Eloquentモデル(モデルのこと)をシリアライズするメソッドを持つクラス。詳しいことは説明が見つからずよくわからなかったが、Mailableクラスとキューに関係するクラスのuse宣言をしている。
・__construct()
コンストラクタ。クラスをインスタンス化した初回時に実行する処理を記述する。▼コンストラクタの使用例
コントローラのsendアクションから渡されたデータを受け取り、プロパティに代入する場合などに使える。
Controllerのsendアクション$params = array(); $params['name'] = 'your name'; Mail::to('送信先メールアドレス')->send(new ContactReply($params));↓ インスタンス生成時にデータ
$paramas
を渡すContactReply.phppublic function __construct($params) { $this->params = $params; }paramsプロパティに
$params
が入る。
・build()
build関数の中にメール本文となるビューの指定などを記述する。Mailableのbuildメソッドの例public function build() { return $this->view('emails.text') ->subject('メールの標題'); }・
view('emails.text')
メール本文になるビューを指定。・
subject('メールの標題')
メールのタイトルを指定。
Mailableで使える主なメソッド
メソッド 概要 使用例 view('ビュー') メール本文となるビューを指定 view('emails.text') subject('') メールのタイトルを指定 subject('お問い合わせ') with([]) データを渡す with(['orderName' => $this->order->name])
attach('ファイルパス') データを添付する。第2引数でファイル名やmimeタイプを指定可能 attach(public_path('img/cat.jpg') attachFromStorage('ファイルパス') ファイルシステム(オンラインストレージ)のデータを添付する attachFromStorage('/path/to/file') text('ビュー') 平文で表示するビューを指定 text('emails.text_plain') ・平文テキストとは?
暗号化していないデータ。指定したビューの内容をそのまま送る。
3. コントローラの作成
・
$ php artisan make:controller コントローラ名
▼実例
$ php artisan make:controller MailableController Controller created successfully.MailableController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Mail; //追記 use App\Mail\ContactReply; //追記 class MailableController extends Controller { //以下追記 public function index() //コンタクトフォームの表示 { return view('contact.index'); } public function send(Request $request) //メールの自動送信設定 { Mail::to('hlaupcpky38@gmail.com') ->send(new ContactReply()); return back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。'); //送信完了を表示 } }基本的な記述はMailableを使用しないコントローラと同じ。
▼変更点
・
use App\Mail\ContactReply;
生成したMailableクラスを使う宣言をする。・
send(new ContactReply())
sendメソッドの引数でMailableクラスのインスタンスを渡す。
4. ルーティングの作成
ルーティングに作成したコントローラのアクションを登録する。
routes > web.php に以下を追記。
web.phpRoute::get('contact2', 'MailableController@index'); Route::post('contact2', 'MailableController@send');・1行目
URL /contact2にアクセスしたときに、ContactControllerのindexアクションを実行する。・2行目
/contact2ページでpostメソッドが使われたとき、ContactControllerのsendアクションを実行する。formのactionでこのパスを指定しておく。
(注意点)Laravel8の場合
Laravel8の場合、デフォルトではコントローラの名前空間を完全なパスで表記しなければいけない。
省略表記するためには、app > Providers > RouteServiceProvider.phpのコメントアウトを解除する。(以下ページ参照)
5. コンタクトフォームの作成(view)
/contactにアクセスしたときに表示するビューを作成する。
indexアクションで
view('contact.index')
を指定しているので、resources > views > contact > index.blade.php を作成する。views配下ならどこでもいいが、contactディレクトリを作成するのはコンタクトフォームに様々な種類ができたときにまとめて保存しておくため。
index.blade.php@if ( Session::has('sent')) <div> <p>{{old('name')}}さん、{{ session('sent') }}</p> </div> @endif <form action="{{ url('contact2') }}" method="POST"> @csrf <p>名前:<input type="text" name="name"></p> <input type="submit" value="送信"> </form>submitボタンをクリックすると、actionで指定したcontact2のページにPOSTメソッドでアクセスし、ルーティングでコントローラのsendアクションを実行する。
・
@if ( Session::has('sent'))
withメソッドで渡されたデータ(キー名:sent)が存在するなら以下のdivタグを表示する。つまり、送信ボタンが押された場合にこのdivタグが表示される。
Controllerのsentアクションreturn back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。');・old('name')
withInput()
で渡されたデータ・session('sent')
with()
で渡されたデータ
6. メール内容の作成(view)
送信されるメール本文となるビューを作成する。
コントローラのsendアクションでビューをemails.text
と指定しているので、以下パスにファイルを作成する。resources > views > emails > text.blade.php
text.blade.phpemailsディレクトリのtext.blade.phpの内容です。
7. サーバーを起動とメール送信処理の実行
$ php artisan serve http://127.0.0.1:8000/http://127.0.0.1:8000/contact2 にアクセスする。
↓ contacts.index.blade.phpの内容が表示される
↓ 「送信」をクリック
▼Gmailの受信内容ページも表示され、Gmailにもメッセージが届いている。
以上でMailableを使ったメールの送信が完了。
以降は応用編として。
メールにデータを添付する方法
ファイルや画像をメールに添付する方法について。
Mailableの
attach
メソッドを使うことで簡単に添付できる。・
attach('ファイルのパス')
▼パス指定の注意点
パスはURIではなくディレクトリパスを指定する。・OK: public_path('img/cat.jpg')
戻り値はディレクトリパスになる。・NG: assets('img/cat.jpg')
戻り値はURI。ContactReply.phppublic function build() { //以下追記 return $this->view('emails.text') ->subject('メールの標題') ->attach(public_path('img/cat.jpg')); }・
attach(public_path('img/cat.jpg'))
public_pathヘルパ関数はpublicディレクトリ配下のパスを指定することで完全なパスを返す。画像を設置する
今回の場合は、 public > img > cat.jpg
画像の添付に成功。
storageディレクトリを活用する方法
publicディレクトリは公開されているディレクトリのため、公開していないアセットを送りたい場合は、storageディレクトリに設置する方法がある。
・
attach(storage_path('ファイルパス'))
ファイルパスにstorage配下のパスを指定すればOK。
メール本文に画像を埋め込む方法
メールに添付する以外に、メール本文に画像を埋め込むことも可能。
<img src="{{ $message->embed(ファイルパス) }}" >
$message
はLaravelが自動生成する。定形として使用。embed
メソッドでファイルパスを指定するこの場合も、
asset
ヘルパー関数でURLを指定するのではなく、ディレクトリのパスを指定する。text.blade.phpemailsディレクトリのtext.blade.phpの内容です。 <img src="{{ $message->embed(public_path('img/small-cat.jpg')) }}" alt="">▼メール本文
メール本文にデータを渡す方法
コンタクトフォームに入力されたデータをメール本文に渡す方法について。
変更する必要があるファイルは3つ。
- Controller
- Mailable
- View
- コントローラで入力されたデータを受け取り、Mailableインスタンスに渡す。
- MailableインスタンスからViewにデータを渡す。
- Viewで受け取ったデータを表示する
といった流れとなる。
1. Controllerの変更
MailableController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Mail; use App\Mail\ContactReply; class MailableController extends Controller { public function index() //コンタクトフォームの表示 { return view('contact.index'); } public function send(Request $request) //メールの自動送信設定 { $data = $request->all(); //追記 Mail::to('hlaupcpky38@gmail.com') ->send(new ContactReply($data)); //変更 return back()->withInput() //変更 ->with('sent', '送信完了しました。'); //送信完了を表示 } }・
$data = $request->all();
コンタクトフォームに入力された内容を受け取り、変数dataにいれる。allメソッドでRequestの全データを取得する。
・
send(new ContactReply($data))
Mailableのクラス(ContactReply)からインスタンスを作成した際に$data
を渡すため引数に記載。・
withInput()
withInputの引数を削除。これまでは1つのデータ(name)のみを送信後の画面に渡していたが、すべてのデータを渡すようにする。遷移後のページでデータを参照する時は
old('キー名')
とする。
2. Mailableクラスの変更
コントローラから受け取ったデータ(
$data
)を受け取り、使えるようにする。<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class ContactReply extends Mailable { use Queueable, SerializesModels; public $data; //追記 /** * Create a new message instance. * * @return void */ public function __construct($data) //変更 { $this->data = $data; //追記 } /** * Build the message. * * @return $this */ public function build() { //以下追記 return $this->view('emails.message') ->subject('メールの標題') ->with('data', $this->data); //追記 } }・
public $data;
コントローラからのデータを受け取るため、インスタンスプロパティを用意する。・
$this->data = $data;
__construct
の引数で変数を指定し、受け取ったデータをインスタンスプロパティにセットする。・
->with('data', $this->data);
withメソッドでインスタンスプロパティのデータをviewに渡す。
3. コンタクトフォームのview変更
コンタクトフォームのビューにメアドとメッセージの入力欄を追加する。
index.blade.php@if ( Session::has('sent')) <div> <p>{{old('name')}}さん、{{ session('sent') }}</p> </div> @endif <form action="{{ url('contact2') }}" method="POST"> @csrf <p>名前:<input type="text" name="name" value="{{old('name')}}"></p> <p>メールアドレス:<input type="text" name="email" value="{{old('email')}}"></p> <p>メッセージ: <textarea name="message">{{ old('message') }}</textarea></p> <input type="submit" value="送信する"> </form>・
url('contact2')
urlヘルパ関数で指定したURLの完全なURIを返す。・
old('キー名')
withやwithInputメソッドで渡されたデータを表示する。上記では、送信ボタンをクリック後に入力データがそのまま残るように指定している。
4. メール本文のview変更
メール本文に受け取ったデータを使って表示するコードを追記する。
今回は、新しいファイルを用意して記述する。resources > views > emails > message.blade.php
message.blade.php<p>名前:{{ $data['name'] }}さん</p> <p>メールアドレス:{{ $data['email'] }}</p> <p>---以下メッセージが送信されました---</p> <p>{!! nl2br( $data['message'] ) !!}</p>・
$data['キー名']
Mailableの->with('data', $this->data);
で渡されたデータを取得している。・
{!! !!}
htmlspecialcharsをエスケープせずに呼び出す。
よく見かける{{ }}
はクロスサイトスクリプティング(XSS)防止のため一部の特殊な記号が実行されないように変換される。ここで
{{!! !!}}
を使うのは、ユーザーが打ち込んだ内容をそのまま表示するため。これがないと、改行が
<br />
として表示されてしまい読みづらい。・
nl2br()
改行を改行のまま表示するメソッド。
これがないと、改行がスペースに変換され繋がって表示されてしまう。なので、
{!! nl2br( ) !!}
はユーザーの入力データをそのまま表示するためのコード。以上で修正が完了
5. メール送信結果の確認
↓送信する
送信後も入力内容が表示されている。
▼メールの受信内容入力した内容がそのままメール本文に反映されている。
- 投稿日:2021-01-20T15:54:54+09:00
【PHP初心者】Laravelを2週間触ってみて理解したこと
1.はじめに
初めてLaravelの案件に携わり気づくと2週間が経過したので、振り返り。
ちなみにPHPも触ったことがあまりないので間違いがあれば教えていただけると幸いです;つД`)この記事は自分のアウトプット用ですが、今まではJavaの案件が主だったので、
「JavaからPHP(Laravel)を初めてさわるよー」みたいな方のお役に立てば嬉しいです
※今回は環境構築や開発は特にしません、Laravelのイメージについて書きます2.まずLaravelとは
PHPのWebフレームワークの1つです。
CakePHPとSymfonyなどフレームワークは多くありますが、Laravelはバージョンアップが頻繁で、日本語のドキュメントも多いので人気だそう。Laravelの特徴
- MVCフレームワーク
- 学習コストが低い
- セキュリティ面が安心
- composer(パッケージ管理ツール)を使っているので導入が簡単 ※composerとはPHPのライブラリの依存関係を管理するツール
個人的にJavaのフレームワークでMVCモデルを使ってきたためイメージはしやすかったです。ビューは「Blade」というテンプレートエンジンを使っています。
イメージはこんな感じ。sample.blade.php<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>sample</title> </head> <body> <h1>Bladeのsampleです</h1> @php $msg = 'ここにメッセージが入ります'; @endphp {{-- コメント --}} <p>{{$msg}}</p> </body> </html>ビューに直接PHPが書けたり、割と直感でわかりやすいです。
Bladeの詳細はまた後日~3.Laravelの階層構造をざっくり説明
Laravel直下のフォルダ。(詳細は参考文献に)
ざっと今理解できてる範囲はこのくらいです。
Controllerとか主要なものはapp、resourceにはviewがあります。app -アプリケーションの主要部分 bootstrap config -アプリケーションの設定ファイル database -データベースのマイグレーションやシード public -画像やcss、js resources -view routes -ルートファイル storage -log tests vendor -composerの依存パッケージの内容Laravel直下のファイル。
「.env」ファイルが環境設定できるところです。.editorconfig .env、.env.example -動作環境の設定 .gitattributes、.gitignore .styleci.yml artisan composer.json、package.json phpunit.xml server.php webpack.mix.js4.最後に
今回は時間がないのでここまでということで・・・
次回はルーティングかBladeについて書こうかな(゜_゜)参考文献
- 投稿日:2021-01-20T14:36:24+09:00
【Laravel】Localhostでgmailを使ってメールを送信する方法。Mailableを使わない方法と使う方法。
LaravelでGmailを使って問い合わせがあった場合に自動でメールを送信する機能を作成する。
いろんなサイトで送信方法に関するページがあるが、ControllerとMailableの違いなど、どのファイルがなんの処理をしているのかがわかりにくかったので一つづつ確認しながら作成し理解を深める。
目次
- 概要
- メール送信に必要なファイル
- .envの設定
- コントローラの作成
- ルーティングの作成
- コンタクトフォームの作成(view)
- メール内容の作成(view)
- サーバーを起動とメール送信処理の実行
- Mailableを使ったメール送信
概要
Laravelメールを送信する機能に、
Mailファサード
とMailable
クラスがある。どちらもメール本文となるviewを指定できたりと類似機能があるので混乱のタネになる。
コントローラのsendアクションとMailファサードのsendメソッドも異なるので注意が必要。
MailファサードとMailableクラスの違い
Mailファサード(を使ったコントローラ)は必須だけど、Mailableはなくてもメール送信可能。
Mailableは本文と添付ファイルの組み合わせを複数パターン作るときに便利。
▼
Mailファサード
- コントローラに記述。メール送信に必須。
use Mail;
で読み込む- 使い方は
Mail::メソッド
▼Mailableクラス
- Mailファサードのサポート役
- メール本文を指定できる。
- なくてもメールは送信できる。
- 添付ファイルの指定が簡単。
php artisan make:mail [mailableクラス名]
で生成Mailableを使うパターンと使わないパターンのそれぞれでメールの送信方法を確認する。
メール送信に必要なファイル
ファイル 必須 内容 .env ✔︎ 送信元となるgmailを使うための、環境変数を記述する。メアドとPWなど web.php ✔︎ ルーティングの設定。コンタクトフォームのルートや送信後のPOSTメソッドで実行するアクションの指定など controller ✔︎ Mailファサードで送信先やメッセージの内容を指定する コンタクトフォームのview ✔︎ submitボタンクリックでメール送信を発火する メール本文のview ✔︎ 送信するメールの本文 mailableのクラス メール送信先やメッセージの内容を指定する
.envの設定
Gmailを送信元のメールサーバーとして使うため、環境変数の設定が必須。
ルートディレクトリ直下の.envの下記部分に追記する。
デフォルトMAIL_MAILER=smtp MAIL_HOST=mailhog MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}"↓
変更後MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com //gmailを指定 MAIL_PORT=587 //メッセージ送信のポート(465ではない) MAIL_USERNAME=xxxx@gmail.com //gmailアドレス MAIL_PASSWORD=xxxxxxxxxxxxxxxx //16桁のPW MAIL_ENCRYPTION=tls //tls通信 #MAIL_FROM_ADDRESS=null //gmailの場合不要 MAIL_FROM_NAME="送信者の名前" //メールの送信者に表示される名前Gmailのパスワード
スマホやPCではなくLaravelなどの外部アプリからGmailを使う場合はアプリパスワードを作成する必要がある。
Googleアカウントにログイン
↓
↓ セキュリティ
↓ アプリパスワード
↓ アプリを選択:メール
↓ デバイスを選択:その他(名前を入力) (例:Laravelなどなんでもいい)
↓ アプリを選択:生成
表示された16桁のパスワードをコピー。(一度しか表示されない!)
これで、アプリパスワードの生成が完了。
ポート番号587と465の違い
MAIL_PORT=587
はサイトによっては465を使っているところもある。どちらもメール送信用のポートだが587推奨。
メール送信のプロトコルで指定したSMTP専用のポートが587。
465は過去に使われていた名残で今も使えるが587が正式とのこと。(465はTLS用のポート)
(補足)
MAIL_MAILER=log
の機能Gmailを使うためのMAIL_MAILERにはSMTPを指定している。これをlogに変更すると、メールを送信せずに、メールの内容をログに吐き出すようになる。
Gmailなどを使わずに簡易的にメール機能を確認したい場合に使える。
▼ファイルの出力先
storage > logs > laravel.log▼出力例
laravel.logメッセージを送信しました。 [2021-01-19 02:11:01] local.DEBUG: Message-ID: <c00e537b1a501@127.0.0.1> Date: Tue, 19 Jan 2021 02:11:01 +0000 Subject: =?utf-8?Q?=E3=83=86=E3=82=B9=E3=83=88=E9=80=81=E4=BF=A1?= From: xxx@gmail.com To: xxx@gmail.com MIME-Version: 1.0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
MAIL_FROM_ADDRESSとは?MAIL_USERNAMEとの違い
MAIL_FROM_ADDRESS
とMAIL_USERNAME
に同じメールアドレスを記載している例があるが、gmailの場合MAIL_FROM_ADDRESS
は不要。
MAIL_FROM_ADDRESS
はメールに表示されるメール送信元の表示を変更する機能。gmailの場合は、
MAIL_USERNAME
が送信元のメアドになるため、MAIL_FROM_ADDRESS
を記述してもgmailによって書き換えられてしまう。
MAIL_FROM_NAME
とはMAIL_FROM_NAMEに指定した値が、実際にメール送信された時のメール送信者のところに表示される。
例えば、
MAIL_FROM_NAME="sample sender"
の場合、以下のように表示されるsample sender <xxx@gmail.com>
指定がない場合は、Exampleとなる。
定型のメッセージを返信する機能の作成
まずは、入力内容などを使わず、単に決められたメッセージを返す簡単な機能を作成することで、メール送信ができることを確認する。
1. コントローラの作成
コンタクトフォームの表示とメール送信を行うコントローラを作成する。
作成するのは1ファイルのみでOK。
・
$ php artisan make:controller [コントローラ名]
「app > Http > Controllers > コントローラ名.php」 が生成される。
▼実例$ php artisan make:controller ContactController Controller created successfully.ファイルを開いて以下を追記する。追記するのは3点。
- Mailファサードのuse宣言
- indexアクション(コンタクトフォームの表示)
- sendアクション(メール送信処理)
ContactController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Mail; //追記 class ContactController extends Controller //以下追記 { public function index() //コンタクトフォームを表示 { return view('contact.index'); } public function send(Request $request) //メールの自動送信設定 { Mail::send('emails.text', [], function($data){ $data ->to('送信先のメアド') ->subject('送信メールの表題'); }); return back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。'); //送信完了を表示 } }
use Mailとは?
use Mail
はMailファサードのuse宣言。
Illuminate\Support\Facades\Mail::class
のaliasなので、use Illuminate\Support\Facades\Mail
としても同じ。▼aliasの確認
app > config > app.php にデフォルトで記載されている。app.php'Mail' => Illuminate\Support\Facades\Mail::class,
indexアクションの中身
return view('contact.index');
ルートでContactControllerのindexアクションが指定された場合に、ビューとして、ファイルパス views > contact > index.blade.php を返す。
ルーティングとビューは後ほど作成する。
sendアクションの中身
メール送信機能を担う重要なアクション。
public function send(Request $request) //メールの自動送信設定 { Mail::send('emails.text', [], function($data){ $data ->to('送信先のメアド') ->subject('送信メールの表題'); }); return back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。'); //送信完了を表示 } }▼
public function send(Request $request)
sendはアクション名。引数では、Requestクラスのインスタンスを変数$requestとして渡している。
この手法をメソッドインジェクション(依存注入)と呼ぶ。
▼
Mail::send
Mailファサードのsendメソッドを呼び出している。
▼sendメソッド
send('ビュー', 関数に渡すデータ, 関数)
- 3つの引数はすべて必要でどれかが抜けるとエラーになる。
- 返信用メールにデータ(例えば、宛先や名前など)を渡す場合は、第2引数に記述する。
- 第3引数の関数で宛先やメールタイトルを指定する。
▽データがない場合の記述例Mail::send('emails.text', [], function($data){ //処理 });
▽データがある場合の記述例例1Mail::send('emails.text', ['msg'=>'ありがとう!'], function($message){ //処理 });例2$data = $request->all() //送信されてきたすべてのデータ Mail::send('emails.text', $data, function($message){ //処理 });
※sendメソッドの引数が一つの場合
Mailableクラスを使用する場合はsendメソッドでMailableクラスのインスタンスを渡す。その場合引数は1つとなる。・例:
send(new [Mailableクラス名]($data)
この場合、ファイル上方でMailableクラス名のuse宣言がなされている必要がある。
▼Mailファサードのメソッド一覧
to('メアド', '表示名')
:宛先のメアド。表示名はなくてもいい。subject('テキスト')
:メールの標題cc('メアド')
: cc送信先のメアドbcc('メアド')
: bcc送信先のメアドfrom('メアド', '表示名')
:
・toメソッドの表示名
送信したメールのtoの部分のメールアドレスを、指定した表示名に置き換える。
・fromメソッドの注意点
fromメソッドのメアドは環境変数のMAIL_FROM_ADDRESS
を上書きする処理のためgmailの場合意味をなさない。表示名で
MAIL_FROM_NAME
を上書きすることができる。ただしこの場合でも第一引数にダミーでなんらかのメアドを入れておかないとエラーになる。
returnの処理
returnは送信処理完了後に表示するページや内容を指定する。
returnの記載がない場合、sendアクションが実行されると空白ページが表示される。
・
return redirect('パス');
redirect関数でパスを指定すると、指定したパスに飛ぶ。・
return back();
元のページを表示する。
入力データを渡す方法
ページ遷移をした後に、そのページにフォームの入力データを渡したい場合に使えるメソッドがある。
・
withInput()
入力内容をすべて渡す。データの取得はold('キー名')
・
withInput($request->only(['name']));
特定のデータのみ渡す。・
with('キー名', 'データ')
指定したデータを渡す。「送信完了しました」などを渡せる。受け取りはsession('キー名')
。
if文の条件で存在確認をしたい場合はSession::has('キー名')
▼実例
return back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。');よってこれは、現在のページに(1)キー名がnameのデータと、(2)キー名sentで「送信完了しました。」という2つの情報を渡している。
実際に画面に表示する処理はこの後のビュー作成時に指定する。
2. ルーティングの作成
ルーティングに作成したコントローラのアクションを登録する。
routes > web.php に以下を追記。
web.phpRoute::get('contact', 'ContactController@index'); Route::post('contact', 'ContactController@send');・1行目
URL /contactにアクセスしたときに、ContactControllerのindexアクションを実行する。・2行目
/contactページでpostメソッドが使われたとき、ContactControllerのsendアクションを実行する。
(注意点)Laravel8の場合
Laravel8の場合、デフォルトではコントローラの名前空間を完全なパスで表記しなければいけない。
省略表記するためには、app > Providers > RouteServiceProvider.phpのコメントアウトを解除する。(以下ページ参照)
3. コンタクトフォームの作成(view)
/contactにアクセスしたときに表示するビューを作成する。
indexアクションで
view('contact.index')
を指定しているので、resources > views > contact > index.blade.php を作成する。views配下ならどこでもいいが、contactディレクトリを作成するのはコンタクトフォームに様々な種類ができたときにまとめて保存しておくため。
index.blade.php@if ( Session::has('sent')) <div> <p>{{old('name')}}さん、{{ session('sent') }}</p> </div> @endif <form action="{{ url('contact') }}" method="POST"> @csrf <p>名前:<input type="text" name="name"></p> <input type="submit" value="送信"> </form>・
@if ( Session::has('sent'))
withメソッドで渡されたデータ(キー名:sent)が存在するなら以下のdivタグを表示する。つまり、送信ボタンが押された場合にこのdivタグが表示される。
Controllerのsentアクションreturn back()->withInput($request->only(['name'])) ->with('sent', '送信完了しました。');・old('name')
withInput()
で渡されたデータ・session('sent')
with()
で渡されたデータ
4. メール内容の作成(view)
送信されるメール本文となるビューを作成する。
コントローラのsendアクションでビューをemails.text
と指定しているので、以下パスにファイルを作成する。resources > views > emails > text.blade.php
text.blade.phpemailsディレクトリのtext.blade.phpの内容です。
5. サーバーを起動とメール送信処理の実行
$ php artisan serve http://127.0.0.1:8000/http://127.0.0.1:8000/contact にアクセスする。
↓ contacts.index.blade.phpの内容が表示される
↓ 「送信」をクリック
▼Gmailの受信内容ページも表示され、Gmailにもメッセージが届いている。
Mailableを使ったメール送信
ここまででかなり長くなったので、Mailableを使ったメール送信は別記事で作成します。。
- 投稿日:2021-01-20T14:15:16+09:00
【Laravel】エラー:Target class [コントローラ名] does not exist.の発生原因と対処法。
Laravelでページを表示したときに、以下エラーが出た場合の対処法。
Illuminate\Contracts\Container\BindingResolutionException Target class [ContactController] does not exist. http://127.0.0.1:8001/contactルーティングで指定されたコントローラが存在しない。というエラー。
▼ルーティング例
web.phpRoute::get('contact', 'ContactController@index');コントローラ名を省略表記してる場合に発生する。
対処法
1. コントローラ名があっているか確認
2. RouteServiceProvider.phpのコメントアウトを解除する
3. 完全な名前空間を記載するファイル名(名前空間)が正しい場合は、No2を実行すれば解決する可能性が高い。
No.3でやっていることはNo.2と同じ。
RouteServiceProvider.phpのコメントアウトを解除する
Laravel7までは、
App\Http\Controllers\
が省略できたが、Laravel8からは省略するとエラーが表示されるようになった。以下ファイルのコメントアウトを解除することで、Laravel7と同じ環境にできる。
app > Providers > RouteServiceProvider.php
解除するコメントアウト//protected $namespace = 'App\\Http\\Controllers';
RouteServiceProvider.phpprotected $namespace = 'App\\Http\\Controllers'; //コメントアウトを解除 /** * Define your route model bindings, pattern filters, etc. * * @return void */ public function boot() { $this->configureRateLimiting(); $this->routes(function () { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); }); }
完全な名前空間を記載する
Laravel8のデフォルト状態でも、完全な名前空間を指定すれば問題なく機能する。
▼ルーティング例
web.phpRoute::get('contact', 'ContactController@index');↓修正
web.phpRoute::get('contact', 'App\Http\Controllers\ContactController@index');
まとめ
コメントアウト解除が超簡単なのでおすすめ。
- 投稿日:2021-01-20T12:00:44+09:00
Laravelのfactoryを使って、中間テーブルにデータを挿入したりしてみる。
今回はLaravelのfactory機能を使って、ダミーデータを作成したり、中間テーブルにデータを挿入したりします。
ぶっちゃけ、そこまで難しくありません。
ざっくりしたファクトリーを使用する手順は、
1.ファクトリーを作って、テーブルに挿入するデータのルールを記述する。
2.シーダーを作って、実際にデータを挿入する処理を記述する。
3.作ったシーダーをコマンドで実行できるように登録する。
これだけです。今回は、
novelsテーブル(小説)
とtagsテーブル(タグ)
の中間テーブルnovel_tagテーブル
にデータを挿入する設定です。
また、最大で6つまで小説にタグを設定できるという仮定で進めていきます。それではガンガンやっていきましょう。
1.ファクトリーを作って、テーブルに挿入するデータのルールを記述する。
まずは
novelsテーブル(小説)
とtagsテーブル(タグ)
用のファクトリーを作成します。下記コマンドを実行してください。
php artisan make:factory NovelFactory php artisan make:factory TagFactoryこれで、
app > database > factories
直下にNovelFactory.php
とTagFactory.php
が作成されているはず。それぞれに下記の記述を追加します。
NovelFactory.php<?php use App\Model; use Faker\Generator as Faker; $factory->define(App\Novel::class, function (Faker $faker) { //Usersテーブルの中からランダムに1つのレコードのidを取得する。 $user_id = App\User::all()->random(1)[0]->id; return [ 'title'=>$faker->word, 'summary'=>$faker->sentence, 'user_id'=>$user_id, ]; });TagFactory.php<?php use App\Model; use Faker\Generator as Faker; $factory->define(App\Tag::class, function (Faker $faker) { return [ 'name'=>$faker->word, ]; });簡単に解説しておきます。
まずFactoryを使う時は$factory->define(App\Novel::class, function (Faker $faker) {ココ});
の中にコードを記述します。
$user_id = App\User::all()->random(1)[0]->id;
こちらのコードはUsersテーブルからランダムで1つのレコードを取得。そして、そのレコードのidを取得しています。
randomメソッド
を使えば、引数に与えた数値の数だけ、コレクションの中からインスタンスを取得することができます。
ここで取得したusersテーブルのid
を'user_id'=>$user_id,
で外部キーを実現しています。2.シーダーを作って、実際にデータを挿入する処理を記述する。
次にシーダーを作成します。
php artisan make:seed NovelsTableSeeder php artisan make:seed TagsTableSeederこれで
app > database > seeds
の中にNovelsTableSeeder.php
とTagsTableSeeder.php
ができているはず。こちらのファイルを下記のように変更します。
NovelsTableSeeder.php<?php use Illuminate\Database\Seeder; use App\Tag; use App\User; class NovelsTableSeeder extends Seeder { public function run() { $tags = Tag::all(); // factoryを利用 factory(App\Novel::class, 100) ->create() ->each(function (App\Novel $novel) use ($tags) { //1~6までの数値をランダムで取得 $ran = rand(1, 6); // 中間テーブルに紐付け $novel->tags()->attach( //tagsテーブルからランダムで1~6個のインスタンスを紐づける。 $tags->random($ran)->pluck('id')->toArray(), //attachの第二引数は他のカラムに挿入したい値を入れることができる。 //今回はtag_numberというカラムにランダムで1~6の数値を挿入。これは僕の都合上やってるだけなので、気にしなくてOK。 ['tag_number'=>$ran] ); }); } }TagsTableSeeder.php<?php use Illuminate\Database\Seeder; class TagsTableSeeder extends Seeder { public function run() { factory(App\Tag::class, 50)->create(); } }上記の通りです。
多対多の中間テーブルへの紐付けは
attachメソッド
を使うのが基本です。
第一引数に紐づけるid、第二引数には他のカラムにも値を追加したい場合はその値を指定します。今回の場合は
$novel->tags()->attach
とすることで、中間テーブルのnovel_idカラム
に$novelのid
が保存されます。次にtag_idカラム
の値を指定する必要があるので、attachメソッド
内に記述します。$tags->random($ran)->pluck('id')->toArray(),
$tags
には$tags = Tag::all();
で取得したtagsテーブルの全データが入っています。その中からランダムで1~6個のインスタンスを取得して、それらのidを配列にしています。$ran
は$ran = rand(1, 6);
の部分でランダムで1~6の値を挿入しています。このようにしているのは、小説には1~6個までのタグを指定できるという設定にしているからです。
別に1つしかタグ付けしないなら、下記でOK。$tags->random(1)->value('id'),3.作ったシーダーをコマンドで実行できるように登録する。
最後に
app > database > seeds > DatabaseSeeder.php
にて、今作ったシーダーを登録します。<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call([ TagsTableSeeder::class, //先にコッチ。 NovelsTableSeeder::class, ]); } }先にタグのシーダーを記述しておかないとエラーになるので注意してください。
あとは下記コマンドを実行すればOkです。
php artisan db:seed駆け足でしたが、これにて終了です。
factoryを使えば簡単に大量のデータを作れます。
慣れないうちは大変だと思いますが、ぜひ使ってみてください。