メールの送信

ニュースレターや注文確認などのメールを送信しようとしていますか? Nette Frameworkは、非常に使いやすいAPIを備えた必要なツールを提供します。以下に示します:

  • 添付ファイルを含むメールの作成方法
  • 送信方法
  • メールとテンプレートの結合方法

インストール

ライブラリはComposerツールを使用してダウンロードおよびインストールします:

composer require nette/mail

メールの作成

メールはNette\Mail\Messageクラスのオブジェクトです。次のように作成します:

$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
	->addTo('petr@example.com')
	->addTo('jirka@example.com')
	->setSubject('注文確認')
	->setBody("こんにちは、\nご注文は受け付けられました。");

入力されるすべてのパラメータはUTF-8である必要があります。

addTo()メソッドで受信者を指定する以外に、コピーの受信者をaddCc()で、またはブラインドコピーの受信者をaddBcc()で指定することもできます。setFrom()を含むこれらすべてのメソッドで、受信者を3つの方法で記述できます:

$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');

HTMLで記述されたメール本文はsetHtmlBody()メソッドで渡されます:

$mail->setHtmlBody('<p>こんにちは、</p><p>ご注文は受け付けられました。</p>');

テキスト版を作成する必要はありません。Netteが自動的に生成します。また、メールに件名が設定されていない場合、<title>要素から取得しようとします。

HTML本文に画像を埋め込むことも非常に簡単です。画像が物理的に存在するパスを2番目のパラメータとして渡すだけで、Netteは自動的にメールに含めます:

// 自動的に /path/to/images/background.gif をメールに追加します
$mail->setHtmlBody(
	'<b>Hello</b> <img src="background.gif">',
	'/path/to/images',
);

画像を埋め込むアルゴリズムは、次のパターンを検索します:<img src=...><body background=...>、HTML属性style内のurl(...)、および特別な構文[[...]]

メール送信はもっと簡単になるでしょうか?

メールははがきのようなものです。メールでパスワードやその他のアクセス情報を送信しないでください。

添付ファイル

もちろん、メールに添付ファイルを追加することもできます。これにはaddAttachment(string $file, ?string $content = null, ?string $contentType = null)メソッドを使用します。

// /path/to/example.zip ファイルを example.zip という名前でメールに挿入します
$mail->addAttachment('/path/to/example.zip');

// /path/to/example.zip ファイルを info.zip という名前でメールに挿入します
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// "Hello John!" という内容の example.txt ファイルをメールに挿入します
$mail->addAttachment('example.txt', 'Hello John!');

テンプレート

HTMLメールを送信する場合、Latteテンプレートシステムで記述するのが自然です。どうすればよいでしょうか?

$latte = new Latte\Engine;
$params = [
	'orderId' => 123,
];

$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
	->addTo('petr@example.com')
	->setHtmlBody(
		$latte->renderToString('/path/to/email.latte', $params),
		'/path/to/images',
	);

email.latteファイル:

<html>
<head>
	<meta charset="utf-8">
	<title>注文確認</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>こんにちは、</p>

	<p>注文番号 {$orderId} のご注文は受け付けられました。</p>
</body>
</html>

Netteは自動的にすべての画像を挿入し、<title>要素に基づいて件名を設定し、HTMLのテキスト代替を生成します。

Nette Applicationでの使用

Nette Application、つまりPresenterと一緒にメールを使用する場合、テンプレート内でn:href属性または{link}タグを使用してリンクを作成したい場合があります。Latteはデフォルトではこれらを知りませんが、追加するのは非常に簡単です。リンクの作成はNette\Application\LinkGeneratorオブジェクトが行い、依存性注入を使用して渡してもらうことでアクセスできます:

use Nette;

class MailSender
{
	public function __construct(
		private Nette\Application\LinkGenerator $linkGenerator,
		private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
	) {
	}

	private function createTemplate(): Nette\Application\UI\Template
	{
		$template = $this->templateFactory->createTemplate();
		$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
		return $template;
	}

	public function createEmail(): Nette\Mail\Message
	{
		$template = $this->createTemplate();
		$html = $template->renderToString('/path/to/email.latte', $params);

		$mail = new Nette\Mail\Message;
		$mail->setHtmlBody($html);
		// ...
		return $mail;
	}
}

テンプレートでは、慣れている方法でリンクを作成します。LinkGeneratorを介して作成されたすべてのリンクは絶対リンクになります。

<a n:href="Presenter:action">リンク</a>

メールの送信

Mailerはメール送信を担当するクラスです。Nette\Mail\Mailerインターフェースを実装しており、いくつかの事前に準備されたメーラーが利用可能です。これらを紹介します。

フレームワークは、設定に基づいて構築されたNette\Mail\Mailer型のサービスをDIコンテナに自動的に追加します。このサービスには、依存性注入を使用して渡してもらうことでアクセスできます。

SendmailMailer

デフォルトのメーラーはSendmailMailerで、PHP関数mailを使用します。使用例:

$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);

returnPathを設定したいが、サーバーがそれを上書きし続ける場合は、$mailer->commandArgs = '-fMuj@email.cz'を使用します。

SmtpMailer

SMTPサーバー経由でメールを送信するには、SmtpMailerを使用します。

$mailer = new Nette\Mail\SmtpMailer(
	host: 'smtp.gmail.com',
	username: 'franta@gmail.com',
	password: '*****',
	encryption: 'ssl',
);
$mailer->send($mail);

コンストラクタには、次の追加パラメータを渡すことができます:

  • port – 設定されていない場合、デフォルトの25またはsslの場合は465が使用されます
  • timeout – SMTP接続のタイムアウト
  • persistent – 永続的な接続を使用する
  • clientHost – クライアントのHostヘッダーを設定する
  • streamOptions – 接続のためのSSLコンテキストオプション

FallbackMailer

メールを直接送信するのではなく、一連のメーラーを介して送信を仲介します。1つのメーラーが失敗した場合、次のメーラーで試行を繰り返します。最後のメーラーも失敗した場合、最初のメーラーから再度開始します。

$mailer = new Nette\Mail\FallbackMailer([
	$smtpMailer,
	$backupSmtpMailer,
	$sendmailMailer,
]);
$mailer->send($mail);

コンストラクタの追加パラメータとして、試行回数とミリ秒単位の待機時間を指定できます。

DKIM

DKIM(DomainKeys Identified Mail)は、メールの信頼性を高める技術であり、偽装されたメッセージの検出にも役立ちます。送信されたメッセージは送信者のドメインの秘密鍵で署名され、この署名はメールのヘッダーに保存されます。 受信者のサーバーはこの署名を、ドメインのDNSレコードに保存されている公開鍵と比較します。署名が一致することで、メールが実際に送信者のドメインから来たものであり、メッセージの転送中に変更されていないことが証明されます。

メールの署名は、設定でメーラーに直接設定できます。依存性注入を使用しない場合は、次のように使用します:

$signer = new Nette\Mail\DkimSigner(
	domain: 'nette.org',
	selector: 'dkim',
	privateKey: file_get_contents('../dkim/dkim.key'),
	passPhrase: '****',
);

$mailer = new Nette\Mail\SendmailMailer; // または SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);

設定

Nette Mailの設定オプションの概要。フレームワーク全体ではなく、このライブラリのみを使用している場合は、設定の読み込み方法をお読みください。

メール送信には、デフォルトでNette\Mail\SendmailMailerメーラーが使用され、これはさらに設定されません。ただし、Nette\Mail\SmtpMailerに切り替えることができます:

mail:
	# SmtpMailer を使用します
	smtp: true       # (bool) デフォルトは false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) デフォルトは null ('secure' というエイリアスがあります)
	clientHost: ...  # (string) デフォルトは $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) デフォルトは false

	# SMTP サーバーへの接続コンテキスト、デフォルトは stream_context_get_default()
	context:
		ssl:         # オプションの概要は https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # オプションの概要は https://www.php.net/manual/en/context.http.php
			header: ...
			...

context › ssl › verify_peer: falseオプションを使用すると、SSL証明書の検証を無効にできます。アプリケーションが脆弱になるため、これを行うことは強くお勧めしません。代わりに、証明書をストアに追加してください

信頼性を高めるために、DKIM テクノロジーを使用してメールに署名できます:

mail:
	dkim:
		domain: myweb.com
		selector: lovenette
		privateKey: %appDir%/cert/dkim.priv
		passPhrase: ...

DIサービス

これらのサービスはDIコンテナに追加されます:

名前 説明
mail.mailer Nette\Mail\Mailer メールを送信するクラス
mail.signer Nette\Mail\Signer DKIM 署名
バージョン: 4.0