====== PHPでシンプルなメールの送信&受信したメールの解析 - MailMan.php ======
{{php-tool-box:email-3.png|}}
送信はmb_send_mail()のラッパーなので、[[http://jp2.php.net/manual/ja/ref.mbstring.php|mb_send_mail()用の設定]](mbstring.language = Japanese とmbstring.internal_encoding)がされていないと文字化けする。
メール解析は[[http://pear.php.net/package/Mail_mimeDecode|PEAR::Mail_mimeDecode]]のラッパーなので、Mail_mimeDecodeのインストールが必要。
Windowsでのみ動作確認した。
===== ちょっとした機能 =====
* 宛先や送信元のメールアドレスに、下記のような表示名を付けられる "山田太郎 "
* 解析したメールに対して、返信を返せる
===== ソースコード =====
from = $from;
$this->to = $to;
$this->subject = $subject;
$this->body = $body;
$this->files = array();
}
/**
* 送信元メールアドレスに表示名をセットする
* @param string $from 表示名
*/
public function setFromName($name) {
$this->fromName = MailMan::_toDisplayName($this->from, $name);
}
/**
* 宛先メールアドレスに表示名をセットする
* @param string $from 表示名
*/
public function setToName($name) {
$this->toName = MailMan::_toDisplayName($this->to, $name);
}
/**
* メールを送信する
* @param array $headerVal メールヘッダーの追加オプション
* @return string 送信成功の場合空文字、失敗の場合メール情報
*/
public function send($headerVal = array()) {
ini_set("sendmail_from", $this->from); //WindowsではSMTPのMAIL FROM(エンベロープFrom)に使われる
//メールヘッダー作成
if ($this->fromName) {
$headerVal['From'] = $this->fromName;
}
if ($this->toName) {
$headerVal['To'] = $this->toName; //表示名付きのToで上書き
}
foreach ($headerVal as $k => $v) {
$header[] = ucfirst($k) . ": $v";
}
//送信(第1引数はSMTPのRCPT TO(エンベロープTO)にも使われる)
if (@mb_send_mail($this->to, $this->subject, $this->body, implode("\r\n", $header))) {
return '';
} else {
return $this->_toString($header);
}
}
/**
* メール内容を見やすい形にする
* @param array $header メールヘッダー情報
*/
protected function _toString($header) {
$s .= "[MAIL FROM]:{$this->from}\n";
$s .= "[RCPT TO]:{$this->to}\n";
$s .= "[header]:\n";
foreach ($header as $line) {
$s .= "$line\n";
}
$s .= "[subject]:{$this->subject}\n";
$s .= "[body]\n";
$s .= "{$this->body}\n";
return $s;
}
/**
* 返信する
* @param string $msg 返信メッセージ
* @return string 送信成功の場合空文字、失敗の場合メール情報
*/
public function reply($msg, $header = array()) {
//元のメッセージを引用として付ける
$msg .= "\n\n";
$lines = split("\n", $this->body);
foreach ($lines as $line) {
$msg .= '> ' . $line . "\n";
}
$reply = new MailMan($this->to, $this->from, 'RE: ' . $this->subject, $msg);
//メールアドレスの表示名をセット
if ($this->fromName) {
$reply->toName = mb_encode_mimeheader($this->fromName);
}
if ($this->toName) {
$reply->fromName = mb_encode_mimeheader($this->toName);
}
return $reply->send($header);
}
/**
* メールのファイルからデータを取り出す($pathか$dataのどちらかのみ渡すこと)
* @param string $path メールのファイルパス
* @param string $data メールの生データ
* @return MailMan 取り出したメール
*/
public static function file2mail($path, $data = "") {
$decoded = MailMan::decode($path, $data);
//基本情報を取り出す
$fromName = MailMan::_jis2internal($decoded->headers['from']);
$toName = MailMan::_jis2internal($decoded->headers['to']);
$from = MailMan::_toOnlyEmail($fromName);
$to = MailMan::_toOnlyEmail($toName);
$subject = MailMan::_jis2internal($decoded->headers['subject']);
$mail = new MailMan($from, $to, $subject, '');
$mail->fromName = $fromName;
$mail->toName = $toName;
//本文と添付ファイルを掘り出す
MailMan::_digBody($mail, $decoded);
return $mail;
}
/**
* メールを分解する($pathか$dataのどちらかのみ渡すこと)
* @param string $path メールのファイルパス
* @param string $data メールの生データ
* @return object 分解したメールデータ
*/
public static function decode($path, $data = "") {
require_once('Mail/mimeDecode.php'); //要PEAR
if (!$data) {
$data = file_get_contents($path);
}
$decoder = new Mail_mimeDecode($data);
$params['decode_headers'] = true;
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
return $decoder->decode($params);
}
/**
* 本文と添付ファイルを取り出す再帰処理
* @access private
*/
private static function _digBody($mail, $part) {
if (is_array($part) || is_object($part)) { //子要素がある場合は再帰処理
foreach($part as $child) {
MailMan::_digBody($mail, $child);
}
}
if (!$part->ctype_primary) {
return;
}
switch (strToLower($part->ctype_primary)) {
case 'multipart':
return;
case 'text': //本文
if (strToLower($part->ctype_secondary) == "plain") { //プレーンテキストのみが対象
$mail->body = MailMan::_jis2internal($part->body);
}
break;
default: //添付ファイル
$file['name'] = MailMan::_jis2internal($part->d_parameters['filename']);
$file['type'] = $part->ctype_primary . '/' . $part->ctype_secondary;
$file['data'] = $part->body;
$mail->files[] = $file;
}
}
/**
* JISから内部文字コードに変換
* @access private
*/
private static function _jis2internal($str) {
return mb_convert_encoding($str, mb_internal_encoding(), 'JIS');
}
/**
* メールアドレスに表示名を加える
* @private
*/
private static function _toDisplayName($email, $name) {
return mb_encode_mimeheader($name) . " <$email>";
}
/**
* メールアドレスだけを取り出す
* @private
*/
private static function _toOnlyEmail($displayName) {
return preg_replace('/(^.*<|>$)/', '', $displayName);
}
}