※当ブログではアフィリエイト広告を利用しています。
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サーバを用意しなくても簡単にメールが送信できるのは開発者にとっては嬉しいと思いました。