【CakePHP入門】メールを送信する方法

こんにちは!フリーエンジニアのせきです。

CakePHPには、メールを送信する機能が用意されています。

この記事では、

・CakePHPでメールを送信する方法を知りたい

という基本的な内容から、

・CakePHPでメール送信できない原因を知りたい

といった応用的な内容に関しても解説していきます。

今回はCakePHPでメールを送信する方法について、わかりやすく解説します!

目次

メールを送信する方法

トランスポートの設定

トランスポートはメール送信に必要な様々な情報を持ちます。

トランスポートの設定は、「[プロジェクトのパス]/config/app.php」の’EmailTransport’で行います。

-省略-
    'EmailTransport' => [
        'default' => [
            'className' => 'Smtp',
            'host' => 'localhost',
            'port' => 25,
            'timeout' => 30,
            'username' => 'user',
            'password' => 'pass',
            'tls' => null,
        ],
    ],
-省略-

‘default’の部分は任意の名前をつけることができ、複数のトランスポートを設定することができます。

ここでつけた名前は、送信するプログラムから指定されます。

設定項目を順番に解説していきいます。

・className
Mail、Smtp、Debugのいずれかを指定します。

Mailを指定した場合は、PHPのmail関数を使用してメールを送信します。

Smtpを使用した場合は、これ以降で設定する外部のSMTPサーバを使用してメールを送信します。

Debugを指定した場合は、デバッグ用で実際にメール送信は行いません。

これ以降の項目は、classNameにSmtpを指定した場合のみ使用されます。

・host、port
使用するSMTPサーバのホスト名とポート番号を指定します。

・timeout
SMTPサーバへの接続のタイムアウト時間を指定します。

・username、password
SMTPサーバに接続するユーザ名とパスワードが必要な場合に指定します。

・tls
TLS(データを暗号化して送受信するプロトコル)を使用する場合はtrueを指定します。

設定値が文字列の場合はシングルクォーテーション(’)で囲んでください。

PHPのmail関数については、以下の記事で詳しく解説しています。

メールを送信する

メールを送信するにはEmailクラスを使用します。

そのため、以下のように送信するクラスでEmailクラスをロードするのを忘れないようにしてください。

use Cake\Mailer\Email;

最初にEmailインスタンスを作成します。

コンストラクタに定義しておいたトランスポートの設定名を指定することで、その設定でメールが送信されます。

コンストラクタでは指定せずに、setProfileメソッドを使用することもできます。

// コンストラクタで指定
$email = new Email('default');

// profileメソッドで指定
$email = new Email();
$email->setProfile('default');

その後、Emailクラスのセッターメソッドを使用し、送信元や宛先などの設定を行います。

$email->setFrom(['送信元アドレス' => '送信者名'])
	->setTo('宛先')
	->setCc('CCの宛先')
	->setBcc('BCCの宛先')
	->setSubject('件名')
	->send('本文');

最後にsendメソッドで、指定した本文が送信されます。

宛先、CC、BCCが複数の場合はメールアドレスを配列で指定することができます。

これらの設定は、「[プロジェクトのパス]/config/app.php」の’Email’で行うことでもできます。

-省略-
    'Email' => [
        'default' => [
            'transport' => 'default',
            'from' => 'from@samurai.jp',
        ],
    ],
-省略-

以下に簡単なメール送信のサンプルを紹介します。
[プロジェクトのパス]/src/Controller/MailController.php

<?php
namespace App\Controller;

use Cake\Mailer\Email;
use App\Controller\AppController;

class MailController extends AppController
{
    public function index()
    {
		$email = new Email('default');
		$email->setFrom(['from@samurai.jp' => 'samurai'])
			->setTo('to@samurai.jp')
			->setSubject('Test Mail')
			->send('test message.');
    }
}

[プロジェクトのパス]/src/Template/Mail/index.ctp

<p>メール送信しました</p>

このサンプルを実行すると、以下のようなメールが送信されます。

差出人:from@samurai.jp
宛先:to@samurai.jp
件名:Test Mail
test message.

Mailerを使用した送信方法

Mailerとは

CakePHP3.1.0からMailerクラスが追加され、メール送信機能をひとつのクラスにまとめることができるようになりました。

たとえば、ユーザ管理を行うアプリケーションで、ユーザ登録完了メール、ユーザ情報変更通知メール、ユーザ退会完了メールのように、ユーザに関連するメールをひとつのMailerクラスにまとめておくと、アプリケーションのどこからでもそのMailerクラスを使用して、ユーザにメールを送信することができます。

Mailerの使い方

Mailerクラスは[プロジェクトのパス]/src/Mailerに作成します。

この章では、ユーザ登録を行い、登録されたメールアドレスに登録完了メールを送信するアプリケーションを作成し、解説していきます。

以下のようなテーブルを作成します。

create table users
(
	id int not null auto_increment, -- ID
	name varchar(32), -- 名前
	email varchar(64), -- メールアドレス
 	primary key (id)
);

bakeで、Model、Template、Controllerを一括で作成します。

「[プロジェクトのパス]/bin」で、以下のコマンドを実行します。

cake bake all users

次に、Mailerクラスを作成します。

[プロジェクトのパス]/src/Mailer/UserMailer.php

<?php
namespace App\Mailer;

use Cake\Mailer\Mailer;

class UserMailer extends Mailer
{
	public function register($user)
	{
		$this
			->setProfile('default')			// トランスポートの設定
			->setTo($user->email)			// 宛先の設定
			->setSubject('ユーザ登録完了')	// 件名の設定
			->setTemplate('register_mail')	// テンプレートの設定
			->viewVars(['user' => $user]);	// テンプレートに渡す変数
	}
}

Emailクラスは「$this」でアクセスすることができます。

宛先の設定には「$user->email」を指定し、登録されたユーザのメールアドレスに送信されるようにしています。

setTemplateメソッドは、メールの本文にテンプレートを使用する時に使用します。

「setTemplate(‘register_mail’)」のように指定すると、「src\Template\Email\text\register_mail.ctp」がテンプレートとして使用されます。

テンプレートには変数を渡すことができviewVarsメソッドに「テンプレートでの変数名 => 渡す変数」の形式で指定します。

続けてテンプレートを作成します。

[プロジェクトのパス]/src\Template\Email\text\register_mail.ctp

<?= $user->name ?>様

会員登録が完了しました。

Controllerで、Mailerクラスを使用してメール送信する処理を追加します。

[プロジェクトのパス]/src/Controller/UsersController.php

<?php
namespace App\Controller;

use Cake\Mailer\MailerAwareTrait; // 追加
use App\Controller\AppController;

class UsersController extends AppController
{

	use MailerAwareTrait; // 追加

    public function add()
    {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
				$this->getMailer('User')->send('register', [$user]); // 追加

                $this->Flash->success(__('The user has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
        $this->set(compact('user'));
        $this->set('_serialize', ['user']);
    }

	// 他メソッド省略

}

MailerAwareTraitクラスを使用するため、「use Cake\Mailer\MailerAwareTrait;」「use MailerAwareTrait;」の記述が必要です。

「$this->getMailer(‘User’)->send(‘register’, [$user]);」で、UserMailerクラスのregisterメソッドを引数$userで呼び出します。

引数が複数ある場合は、配列で指定することができます。

以下の画面に名前とメールアドレスを入力して、SUBMITボタンを押します。
mail

入力したメールアドレスに、以下のメールが送信されます。

差出人:from@samurai.jp
宛先:to@samurai.jp
件名:ユーザ登録完了
たなか様

会員登録が完了しました。

bakeについては、以下の記事で詳しく解説しています。

メールを送信できない場合

メール送信に失敗するには、いくつかの原因が考えられます。

実行時に表示されることのあるエラーと原因です。

・Call to undefined method App\Controller\UsersController::getMailer()
MailerAwareTraitクラスがロードできていません。「use Cake\Mailer\MailerAwareTrait;」「use MailerAwareTrait;」の記述を見直してください。

・php_network_getaddresses: getaddrinfo failed:
SMTPサーバの設定が間違っている可能性があります。設定を見直してください。

・From is not specified.
送信元が指定されていません。送信元は必須ですので、app.phpの’Email’に設定するか、プログラムでsetFromメソッドを使用し設定してください。

宛先が間違っていてメールが届かない場合はエラーにはなりませんので、注意してください。

まとめ

今回はCakePHPでメールを送信する方法について解説しました。

会員登録を行うサイトなどの構築では、メール機能が必須となってきますので使い方をしっかり覚えましょう。

メールを送信する方法を忘れてしまったら、この記事を思い出して下さい!

この記事を書いた人

フリーランスでWebシステム開発やゲーム開発をしています。
読者の方にプログラミングの面白さをお伝えしたいです。

目次