読者です 読者をやめる 読者になる 読者になる

しぃぶろぐ。

仕事とか技術関係のこと。

メールを分解する。の解説。

えーと、既にどれくらい前なのかよくわからなくなってしまいましたが。
前に貼り付けたソース(修正版)の解説です。
長いです。

<?php
set_include_path(get_include_path().PATH_SEPARATOR.'/home/ユーザー名/PEARルートフォルダ/PEAR/');
require_once 'Mail/mimeDecode.php';
$params['include_bodies'] =true;
$params['decode_bodies'] =true;
$params['decode_headers'] =true;
$params['input'] = file_get_contents("php://stdin");
$params['crlf'] = "\r\n";
$mail_data = Mail_mimeDecode::decode($params);

#-- From
$FromAddress = $mail_data->headers['from'];
$FromAddress = addslashes($FromAddress);
$FromAddress = str_replace('"','',$FromAddress);
preg_match("/<.*>/",$FromAddress,$str);
if($str[0]!=""){
        $str=substr($str[0],1,strlen($str[0])-2);
        $FromAddress=$str;
}

$Subject = $mail_data->headers['subject'];
$Subject = mb_convert_encoding($Subject,"UTF-8","JIS");

switch(strtolower($mail_data->ctype_primary)){
        case "text":
         $MailBody = $mail_data->body;
         $MailBody = mb_convert_encoding($MailBody,"UTF-8","JIS");
         break;
        case "multipart":
         foreach($mail_data->parts as $part){
                switch(strtolower($part->ctype_primary)){
                        case "text":
                         $MailBody = $part->body;
                         $MailBody = mb_convert_encoding($MailBody,"UTF-8","JIS");
                         break;
                        case "image":
                         $type = strtolower($part->ctype_secondary);
                         if($type != "jpeg" and $type != "jpg" and $type != "gif" and $type != "png"){
                                continue;
                         }
                         $fp = fopen("/home/ユーザー名/プログラムフォルダ/tmp/". time() . $type, "w");                       
              $length = strlen($part->body);
                         fwrite($fp,$part->body,$length);
                         fclose($fp);
                         break;
                }
         }
         break;
        default:
         $MailBody="";
         break;
}
$fp = fopen("/home/ユーザー名/プログラムフォルダ/test.txt","w");
fwrite($fp,$MailBody."\r\nend\r\n");
fclose($fp);
?>


長いので、解説は続きで。
まず、一行目。

set_include_path(get_include_path().PATH_SEPARATOR.'/home/ユーザー名/PEARルートフォルダ/PEAR/');

PEARのパッケージディレクトリを、パスに追加しています。
パスの指定は別のやり方があるはずですが、ここではプログラム内で直接設定(set_include_path)しています。
get_include_path()は、現在のパスを取得。
PATH_SEPARATORは、OSに依存しないパスセパレータ(パスを追記する際に使用するセパレータ。Winだと;)。
.は文字連結です。


次に、

require_once 'Mail/mimeDecode.php';
$params['include_bodies'] =true;
$params['decode_bodies'] =true;
$params['decode_headers'] =true;
$params['input'] = file_get_contents("php://stdin");
$params['crlf'] = "\r\n";
$mail_data = Mail_mimeDecode::decode($params);

で、mimeDecodeのパッケージを読み込み(require_once)。
Mail_mimeDecode::decodeの引数($params)を各種設定し、
デコード結果を$mail_dataに入れています。


その後、メールを分解して各変数におさめていきます。

$FromAddress = $mail_data->headers['from'];
$FromAddress = addslashes($FromAddress);
$FromAddress = str_replace('"','',$FromAddress);
preg_match("/<.*>/",$FromAddress,$str);
if($str[0]!=""){
        $str=substr($str[0],1,strlen($str[0])-2);
        $FromAddress=$str;
}

$Subject = $mail_data->headers['subject'];
$Subject = mb_convert_encoding($Subject,"UTF-8","JIS");

$mail_dataからヘッダーのfrom(差出人アドレス)を取り出し、$fromAddressに入れます。
addslashes()は文字列をエスケープしてくれます(クォートされるべき記号をクォートしてくれる)。
ダブルコーテーションは削除し、差出人アドレス内に署名が混じっていた場合は、
preg_matchとそれに続くif文内で削除しています。
そして、$mail_dataからsubject(メールタイトル)を取り出して$Subjectに入れています。

switch(strtolower($mail_data->ctype_primary)){
        case "text":
         $MailBody = $mail_data->body;
         $MailBody = mb_convert_encoding($MailBody,"UTF-8","JIS");
         break;
        case "multipart":
         foreach($mail_data->parts as $part){
                switch(strtolower($part->ctype_primary)){
                        case "text":
                         $MailBody = $part->body;
                         $MailBody = mb_convert_encoding($MailBody,"UTF-8","JIS");
                         break;
                        case "image":
                         $type = strtolower($part->ctype_secondary);
                         if($type != "jpeg" and $type != "jpg" and $type != "gif" and $type != "png"){
                                continue;
                         }
                         $fp = fopen("/home/ユーザー名/プログラムフォルダ/tmp/". time() . $type, "w");                       
              $length = strlen($part->body);
                         fwrite($fp,$part->body,$length);
                         fclose($fp);
                         break;
                }
         }
         break;
        default:
         $MailBody="";
         break;
}

この部分では、本文の内容を$MailBodyに入れています。
メールはテキストとマルチパート(添付ファイルがついていたりするメール)に分かれています。
それを判別しているのがswitch(strtolower($mail_data->ctype_primary))になります。
テキストの場合はほぼそのまま$MailBodyに入れてしまいます。
マルチパート(添付ファイルがある場合)は、
パート(部品)ごとにctype_primaryをチェックし、
テキストなら$MailBodyに、画像の場合は適当なフォルダに保存しています。


最後三行はテストのために、$MailBodyの内容をtest.txtに吐き出しています。
今後は、この最後三行の部分を変更して、
DBを更新したり、差出人にメールを返送したりする予定です。