※当ブログではアフィリエイト広告を利用しています。
PHPからメール送信したいシーンは多くあると思いますが、AWSのAmazon SES(Simple Email Service)というメール配信用サービスを使用する方法があります
AWSが提供している開発キット「AWS SDK for PHP2」を使いメールを送信するサンプルコードを、添付ファイルが無い場合とある場合それぞれについてメモします。
事前準備
Amazon SESおよびAWS SDK for PHP 2を使うにはいくつか事前準備が必要です。
Amazon SESを使用するための事前準備
Amazon SESを使うためには以下のような準備が必要になります。
- 送信元として使用するメールアドレスの確認
- IAM(Identity and Access Management)でメール送信用のAWSユーザを作成
- IAMユーザのアクセスキー・シークレットキーの取得
準備の方法は以前書いた、iOSからAmazon SESを使ってメール送信するための以下のエントリに記載のものと同様です。
関連エントリ:Amazon SESとAWS SDK for iOSを使ってiPhoneからメールを送信する方法
また2014年7月現在、Amazon SESは以下のリージョンでのみ使用可能です。
- US East (N. Virginia)
- US West (Oregon)
- EU (Ireland)
AWS SDK for PHP 2を使用する事前準備
AWS SDK for PHP 2を使用するにはAWS公式サイトよりSDKaws.pharをダウンロードし、PHPでインクルードできる状態にしておきます。
AWS SDK for PHP 2を使用したコーディングサンプル
メール送信のサンプルコードです。添付ファイルが無い場合とある場合それぞれについて記載します。
テキストメールまたはHTMLメールを送信する場合
通常のテキストメールまたはHTMLメールはsendEmail()メソッドを使用することで送信可能です。
<?php
// AWS SDK for PHP 2を読み込む
require_once './aws.phar';
use Aws\Ses\SesClient as SesClient;
use Aws\Common\Enum\Region as Region;
use Aws\Ses\Exception\SesException as SesException;
$aws_access_key = "YOUR_ACCESS_KEY"; // アクセスキー
$aws_secret_key = "YOUR_SECRET_KEY"; // シークレットキー
$source = 'you@example.com'; //送信元アドレス
$dest = 'you@example.com'; //送信先アドレス
$charset = 'ISO-2022-JP'; //変換先の文字コード
$subject = "SESサンプルメール"; //件名
$body_text = "サンプルメールです。\n\nPHP+Amazon SESで送信されました。"; //本文
try {
//アクセスキー、シークレットキー、リージョンを指定しクライアントを生成する
$client = SesClient::factory(
array(
'key' => $aws_access_key,
'secret' => $aws_secret_key,
'region' => Region::OREGON
)
);
//添付ファイル無しのメールを送信
$result = $client->sendEmail(array(
// Source(送信元)は必須
'Source' => $source,
// Destination(宛先)は必須
'Destination' => array(
'ToAddresses' => array($dest), // To
'CcAddresses' => array(), // CC(あれば)
'BccAddresses' => array(), // BCC(あれば)
),
// Message(メッセージ部分)は必須
'Message' => array(
// Subject(件名)は必須
'Subject' => array(
// Data(件名部分データ)は必須
'Data' => $subject,
'Charset' => $charset,
),
// Body(本文)は必須
'Body' => array(
'Text' => array(
// Data(本文データ)は必須
'Data' => $body_text,
'Charset' => $charset,
),
/* HTMLメールを送る場合
'Html' => array(
// Data(HTMLデータ)は必須
'Data' => 'HTMLです',
'Charset' => $charset,
),
*/
),
),
)
);
// 結果を表示
echo '<pre>';
print_r($result);
echo '</pre>';
} catch (SesException $exc) {
echo $exc->getMessage();
}
メール送信の流れは以下のような感じです。
- Amazon SESのクライアントインスタンスを生成
- 送信先・本文などの内容を引数に指定し
sendEmail()メソッドを実行
実際に送信されたメールは以下の画像のようなイメージです。
添付ファイル付きメールを送信する場合
添付ファイル付きメールはsendRawEmail()メソッドを使用することで送信可能です。
<?php
// AWS SDK for PHP 2を読み込む
require_once './aws.phar';
use Aws\Ses\SesClient as SesClient;
use Aws\Common\Enum\Region as Region;
use Aws\Ses\Exception\SesException as SesException;
// 言語と文字エンコーディングをセット
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$aws_access_key = "YOUR_ACCESS_KEY"; // アクセスキー
$aws_secret_key = "YOUR_SECRET_KEY"; // シークレットキー
$source = 'you@example.com'; //送信元アドレス
$dest = 'you@example.com'; //送信先アドレス
$charset = 'ISO-2022-JP'; //変換先の文字コード
$subject = "SESサンプルメール"; //件名
$body_text = "サンプルメールです。\n\nPHP+Amazon SESで送信されました。"; //本文
$filepath = "./images/sample.jpg"; //添付するファイルのパス
try {
// アクセスキー、シークレットキー、リージョンを指定しクライアントを生成する
$client = SesClient::factory(
array(
'key' => $aws_access_key,
'secret' => $aws_secret_key,
'region' => Region::OREGON
)
);
// パートの境界を表す文字列(boundary)
$boundary = "Boundary_(PHP_SES/" . uniqid(rand()) . ")";
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$path_parts = pathinfo($filepath);
$filename = $path_parts['basename']; //ファイルパスからファイル名を取得
$mimetype = finfo_file($finfo, $filename); //ファイルからMIMEタイプを取得
$subject = str_replace("\r", "", mb_encode_mimeheader($subject));
// 本文の文字コードを指定したものにエンコーディングする
$body_text = mb_convert_encoding($body_text, $charset);
// 添付するファイルを読み込んでBase64エンコードする
$attachment_data = base64_encode(file_get_contents($filepath));
// rawメッセージ部分
$message = "To: " . $dest . "\n";
$message.= "From: " . $source . "\n";
$message.= "Subject: " . $subject = str_replace("\r", "", $subject) . "\n";
$message.= "MIME-Version: 1.0\n";
$message.= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"';
$message.= "\n\n";
$message.= "--" . $boundary . "\n";
$message.= 'Content-Type: text/plain; charset=' . $charset;
$message.= "\n";
$message.= "Content-Transfer-Encoding: 7bit\n";
$message.= "Content-Disposition: inline\n";
$message.= "\n";
$message.= $body_text; //本文をISO-2022-JPに変換
$message.= "\n\n";
$message.= "--" . $boundary . "\n";
$message.= 'Content-Type: ' . $mimetype . '; name="' . $filename . '"';
$message.= "\n";
$message.= "Content-Transfer-Encoding: base64\n";
$message.= 'Content-Disposition: attachment; filename="' . $filename . '"';
$message.= "\n";
$message.= $attachment_data;
$message.= "\n";
$message.= "--" . $boundary . "\n";
// SESクライアントからRawメールを送信する
$result = $client->sendRawEmail(array(
'Source' => $source,
'Destinations' => array($dest),
// RawMessage is required
'RawMessage' => array(
// Data is required
'Data' => base64_encode($message),
),
));
// 結果を表示
echo '<pre>';
print_r($result);
echo '</pre>';
} catch (SesException $exc) {
echo $exc->getMessage();
}
メール送信の流れは以下のような感じです。sendEmail()でテキストのみを送信する場合と異なり、メッセージ部分にはmultipart/mixedで複数のパートを格納するメッセージを指定する必要があるのがポイントです。
- Amazon SESのクライアントインスタンスを生成
- 複数のパートを格納するメッセージ部分の文字列を作成
- 送信先・メッセージ部分などの内容を引数に指定し
sendRawEmail()メソッドを実行
マルチパート形式のメッセージについては以下のサイトが参考になりました。
関連サイト:メールヘッダー。~ファイルを添付したらどうなるの?~ | Opentone Labs.
実際に送信されたメールは以下の画像のようなイメージです。ちゃんと画像が添付されています。
おわりに
以前のエントリではAmazon SES + iOSからのメール送信を実装しましたが、実際に使う場面としてはPHPのほうが多いのではないでしょうか。
自分でSMTPサーバを用意しなくても簡単にメールが送信できるのは開発者にとっては嬉しいと思いました。








