メール受信でPHPスクリプトを起動させるための準備(postfix)
サーバーでメールを受信すると同時にコマンドを実行するための設定は「/etc/aliases」と「|(パイプ)」で行います。
「/etc/aliases」とはメールアカウントに対して別名(エイリアス)を設定できるファイルです。あるアカウントに届いたメールを別のアカウントに転送する、メールが届いた際にコマンドを実行する、といった設定ができます。
「info」というアカウントに届いたメールを「hoge」というアカウントに転送する例は次のようになります。
info: hoge
「|(パイプ)」とはあるコマンドの標準出力を別のコマンドの標準入力と連結する記号です。複数のコマンドを一回の操作で実行したい場合に使います。
例えば起動中プロセスの中から「perl」のプロセスのみを閲覧したい場合に次のようにして使用します。
# ps -ef | grep perl
この「/etc/aliases」と「|(パイプ)」を使ってあるアカウントに届いたメールデータをPHPに渡して実行させる、という設定を行います。
以下の記述例は「map」宛てに届いたメールのデータを標準入力として渡して「/var/www/modules/mail_receive.php」のPHPを実行するという意味になります。mapはpostfixの中であらかじめアカウント登録しておく必要があります。
map: "|/usr/local/bin/php /var/www/modules/mail_receive.php"
/etc/aliases に設定を追記した後はnewaliasesコマンドで設定を反映させて、postfixを再起動します。
# newaliases # postfix reload
PHPでメールデータを取得する
/etc/aliasesの設定で起動されたPHPからは、標準入力からstream_get_contents関数でメールデータを取得できます。
標準入力はPHPの予約語である「STDIN」で扱います。
$raw_mail = stream_get_contents(STDIN);
このようにして取得したメールデータをPHP内で解析します。
メールデータを解析する
前項で取得したメールデータはメールシステムの生のデータになりますので、これをMail::mimeDecodeを使って解析していきます。
Mail::mimeDecodeを利用すると今回のように添付ファイルのあるマルチパートのメールでも生メールデータを渡すことでdecodeメソッドで構造を解析できます。
具体的な使い方は次のとおりです。
$params = array(); $params['include_bodies'] = true; // ボディを解析 $params['decode_bodies'] = true; // ボディをコード変換 $params['decode_headers'] = true; //ヘッダをコード変換 $decoder = new Mail_mimeDecode($raw_mail); // 標準入力で取得したメールデータ $structure = $decoder->decode($params);
メール構造解析時に指定できるオプションには以下のものがあります。以下のパラメータを配列で指定することにより解析のレベルを指定できます。
| パラメータ名 | 意味 |
| include_bodies | メールのボディ部分を解析する |
| decode_bodies | メールのボディ部分を内部文字コードに変換する |
| decode_heder | メールのヘッダ部分を内部文字コードに変換する |
今回のサンプルのように添付ファイルを取得する場合は「decode_bodies」を指定していないと正常に添付ファイルを取得できないことがありますので注意が必要です。
decodeメソッドで解析したメールデータの構造のイメージは下図のようになります。


携帯電話で送信されるメールには件名と本文のみのテキストメールと添付ファイルなどのあるマルチパートのメールの場合の2種類があります。
今回は画像が1枚添付されていますのでマルチパートのメールになります。
decodeメソッドで解析した後の$structure内の階層は次のようになります。
| 変数名 | 意味 |
| $structure->headers | メールヘッダの送信元、送信先、メールの件名などの情報が格納されるオブジェクト |
| $structure->ctype_primary | 「text」「multipart」といったメールの種類が入ります |
| $structure->parts | マルチパートの場合に各パートが格納されるオブジェクト |
$structure->ctype_primaryで解析したメールが今回のようにマルチパートである場合は、$structure->partsに入っている構造体を参照して添付ファイルやメール本文を取り出します。
parts以下の構造体のdispositionプロパティを参照して添付ファイルかどうかを判断して、bodyプロパティを参照して添付ファイルの実ファイルを取得します。
送信元やメールの題名などのヘッダ情報は$structure->headersを参照して取得します。
