
目的:
phpにて、添付付きメールを、件名だけ変更して、添付ファイルごと外部へ転送する。
現在、メール受信したものを、mysqlに保存(UID、件名、送信元メールアドレス(一致したものを、指定の件名に変更)、送信日、受信日、本文)、
添付ファイルはサーバー上に保存し、
メール送信時に、サーバー上に保存した添付ファイルとmysqlのデータを読み込み、送信しています。
(添付ファイルは、定期的に削除)
これを、もっと簡潔に出来ないでしょうか。
サーバー上に添付ファイルを残さないで済み、
未受信のメールのみ
1画面上で、添付メールごと転送できるのが理想です。
※mysqlへの保存は、あってもなくてもかまいません。
以下が、現在の状態です。
参考にしたのは、こちらのサイトです。
http://hal456.net/qdmail_rec/top
http://www.favorite-labo.org/view/202
※サーバはCPIです。
**メール受信処理**
<?php
// QdmailReceiver呼び出し
require_once('qdmail_receiver.php');
//POPサーバー(受信サーバー)にアクセスするための初期設定。
$server = array(
'protocol'=>'pop3',
'host'=>'(ホスト名)',
'user'=>'(ユーザー名)',
'pass'=>'(パスワード)',
);
qd_receive_mail( 'start' , $server , 'eucJP-win' );
//オブジェクト指向モードでの初期化
$receiver = QdmailReceiver::start( 'pop' , $server);
for($i = 1 ; $i <= $receiver->count() ; $i++){
$todaydata = date("Y-m-d");
// *************** メールデータ取得処理 ***************
$pointer = $receiver->pointer();// pointer
$popuid = $receiver -> header( 'popuid' );// UID
$subject_name = mb_convert_encoding(($receiver->header( array('subject','name') , 'none' )),"Shift-JIS","auto");//件名
$from_mail = $receiver->header( array('from','mail') , 'none');//送信元メールアドレス
$date = $receiver -> header('date');//送信日
$text = mb_convert_encoding(($receiver->text()),"Shift-JIS","auto");//本文
// *************** UID照合処理 ***************
include '(mysql接続)';
$ii=0;
while ($row = mysql_fetch_assoc($result)) {
$ii++;
}
if($ii == 0){
// *************** 転送前データの保存 ***************
include '(mysql接続)';
// *************** 添付ファイル保存 ***************
$attach = $receiver->attach();
foreach($attach as $att){
$moji = mb_convert_encoding($att['filename'],"Shift-JIS","auto");
$fp=fopen($moji,'w');
fputs($fp,$att['value']);
fclose($fp);
}
}else{
print('取得済みにつき未処理');
}
?>
**メール送信**
<?php
//マイムタイプ定義
$mime_content_types = array(
'ez' => 'application/andrew-inset',
'atom' => 'application/atom+xml',
'atomcat' => 'application/atomcat+xml',
~略~
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk'
);
//送信先メールアドレス
$to = '(送信先メールアドレス)';
//送信元メールアドレス
$from = '(取得した送信元メールアドレス)';
//件名
$subject = '(変更した件名)';
//メール本文
$message = (取得した本文);
//添付ファイル
$files = array('(添付ファイル1へのパス)','(添付ファイル2へのパス)…以下、あるだけ');
//件名・本文をエンコード
$subject = mb_convert_encoding($subject, 'JIS', 'Shift-JIS');
$message = mb_convert_encoding($message, 'JIS', 'Shift-JIS');
$subject = '=?iso-2022-jp?B?' . base64_encode($subject) . '?=';
//バウンダリ文字列を定義
if (empty($files)) {
$boundary = null;
} else {
$boundary = md5(uniqid(rand(), true));
}
//メールボディを定義
if (empty($files)) {
$body = $message;
} else {
$body = "--$boundary\n";
$body .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
$body .= "Content-Transfer-Encoding: 7bit\n";
$body .= "\n";
$body .= "$message\n";
foreach($files as $file) {
if (!file_exists($file)) {
continue;
}
$info = pathinfo($file);
$content = $mime_content_types[$info['extension']];
$filename = basename($file);
$body .= "\n";
$body .= "--$boundary\n";
$body .= "Content-Type: $content; name=\"$filename\"\n";
$body .= "Content-Disposition: attachment; filename=\"$filename\"\n";
$body .= "Content-Transfer-Encoding: base64\n";
$body .= "\n";
$body .= chunk_split(base64_encode(file_get_contents($file))) . "\n";
}
$body .= '--' . $boundary . '--';
}
//メールヘッダを定義
$header = "X-Mailer: PHP5\n";
$header .= "From: $from\n";
$header .= "MIME-Version: 1.0\n";
if (empty($files)) {
$header .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
} else {
$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
}
$header .= "Content-Transfer-Encoding: 7bit";
//メール送信
if (mail($to, $subject, $body, $header)) {
echo 'メールが送信されました。';
} else {
echo 'メールの送信に失敗しました。';
}
?>
以上、よろしくお願いします
No.3ベストアンサー
- 回答日時:
ANo.2のソースに転送処理を組み込んでみました。
とりあえず添付ファイルなどがあっても問題なく転送出来ています。参考にどうぞ。<?php
$server = 'POPサーバ名';
$user = 'メールアカウント';
$pass = 'パスワード';
$log = array();
$dat = array();
$sock = fsockopen($server, 110, $errno, $errstr, 20) or die(sprintf('cannot connect %d, %s', $errno, $errstr));
$buf = fgets($sock, 512);
if(substr($buf, 0, 3) != '+OK') die($buf);
$buf = _sendcmd("USER $user");
$buf = _sendcmd("PASS $pass");
$data = _sendcmd("STAT");//STAT -件数とサイズ取得 +OK 8 1234
sscanf($data, '+OK %d %d', $num, $size);
for($i=1; $i<=$num; $i++) {
$line = _sendcmd("RETR $i");
$dat[$i] = '';
while (!preg_match("/^\.\r\n/", $line)) {
$line = fgets($sock,512);
$dat[$i] .= $line;
}
// $data = _sendcmd("DELE $i");
}
$buf = _sendcmd("QUIT");
fclose($sock);
file_put_contents('pop3log.txt', implode(PHP_EOL, $log));
foreach ($dat as $key=>$val) {
$out = md5(microtime()) . '.txt';
file_put_contents($out, $val);
printf('%03d : %s<br>', $key, $out);
_mailsend($val);
}
function _sendcmd($cmd) {
global $sock, $log;
fputs($sock, $cmd."\r\n");
$log[] = 'send : ' . $cmd;
$buf = fgets($sock, 512);
$log[] = 'recv : ' . $buf;
if(substr($buf, 0, 3) == '+OK') {
return $buf;
} else {
die($buf);
}
return false;
}
function _mailsend($arg) {
$mail = explode("\r\n", $arg);
$head = array();
$body = array();
$sw = 0; // 0:ヘッダ、1~:ボディ
foreach($mail as $line) {
if (trim($line) == '') { $sw++; } // 空行があったらヘッダ終了
if ($sw == 0) { // ヘッダチェック
$hf = false; // 残すヘッダは true
if ((substr($line, 0, 1) != " ")&&(substr($line, 0, 1) != "\t")) {
if (strtolower(substr($line, 0, 7)) == "content") { $hf = true; } // content* は残す
if (strtolower(substr($line, 0, 4)) == "from") { // fromはx-org-fromにして残す
$line = 'x-org-' . $line;;
$hf = true;
}
}
}
switch ($sw) {
case 0:
if ($hf) { $head[] = rtrim($line); }
break;
default:
$body[] = rtrim($line);
break;
}
}
$head[] = 'From: 自分のメールアドレス';
return mail('転送先メールアドレス', 'test', implode("\r\n", $body), implode("\r\n", $head)); // subjectに日本語を使うときはmime処理なども自前で
}
shimix様
御丁寧にありがとうございます。
参考にさせて頂きます。
ただ、私の方で、頂いたソースの
'POPサーバ名';
'メールアカウント';
'パスワード';
'自分のメールアドレス';
'転送先メールアドレス'
部分のみを変更し、実行すると、メールは転送されるのですが、
本文にヘッダーの一部が入り、添付ファイルが添付されていない状態となりました(汗
件名 OKです!
本文 ヘッダーの一部+本文+添付ファイルの文字情報
添付ファイル 添付されていない状態
CPIの環境でしょうか(汗
本日より2日ほど出張の為、
帰ってきたら、頂いたソースを参考に、再チャレンジしてみます。
現在、メール本文は、下記のような状態となっております。
ソース表示ではなく、届いたメールを開いた状態です。
********** メール本文ここから **********
Content-Type: multipart/mixed;
From: (自分のメールアドレス)
X-Brightmail-Tracker: AAAAAA==
X-Brightmail-Tracker: AAAAAA==
This is a multi-part message in MIME format.
--------------050804090906090400040804
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
(本文)
--------------050804090906090400040804
Content-Type: application/x-zip-compressed;
name="test.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="test.zip"
UEsDBAoAAAAAALQJe0QAAAAAAAAAAAAAAAAIAAAAdGVzdC50eHRQSwECPwAKAAAAAAC0CXtE
AAAAAAAAAAAAAAAACAAkAAAAAAAAACAAAAAAAAAAdGVzdC50eHQKACAAAAAAAAEAGAChtlBZ
DknPAaG2UFkOSc8BobZQWQ5JzwFQSwUGAAAAAAEAAQBaAAAAJgAAAAAA
--------------050804090906090400040804--
.
********** ここまで **********
No.2
- 回答日時:
生のメールデータに可能な限り近い状態のテキストってqdmailで扱えませんでしたっけね。
textパート($receiver->text())じゃなくて生メールデータの「テキスト」です。これを間違うと意味がないです。$receiver->body_allとかで採れないのかなぁ・・・。#PEARのNet_IMAPやNet_POP3も保守されてないので
#お勧めしにくいですしね。
POP3限定で自前で(socketで繋いで)メールデータを取得するなら下記のような手法もあります。レッツphpさんの写メールBBSのソース(pop.php)を改変したものです。
<?php
$server = 'pop3サーバ名';
$user = 'メールアカウント or メールアドレス';
$pass = 'パスワード';
$log = array();
$dat = array();
$sock = fsockopen($server, 110, $errno, $errstr, 20) or die(sprintf('cannot connect %d, %s', $errno, $errstr));
$buf = fgets($sock, 512);
if(substr($buf, 0, 3) != '+OK') die($buf);
$buf = _sendcmd("USER $user");
$buf = _sendcmd("PASS $pass");
$data = _sendcmd("STAT");//STAT -件数とサイズ取得 +OK 8 1234
sscanf($data, '+OK %d %d', $num, $size);
for($i=1; $i<=$num; $i++) {
$line = _sendcmd("RETR $i");
$dat[$i] = '';
while (!preg_match("/^\.\r\n/", $line)) {
$line = fgets($sock,512);
$dat[$i] .= $line;
}
// 削除してよければコメントアウトを外す
// $data = _sendcmd("DELE $i");
}
$buf = _sendcmd("QUIT");
fclose($sock);
file_put_contents('pop3log.txt', implode(PHP_EOL, $log)); // ログをファイルに書き出す
foreach ($dat as $key=>$val) {
$out = md5(microtime()) . '.txt'; // メールデータを書き出すファイル名
file_put_contents($out, $val);
printf('%03d : %s<br>', $i, $out);
}
function _sendcmd($cmd) {
global $sock, $log;
fputs($sock, $cmd."\r\n");
$log[] = 'send : ' . $cmd;
$buf = fgets($sock, 512);
$log[] = 'recv : ' . $buf;
if(substr($buf, 0, 3) == '+OK') {
return $buf;
} else {
die($buf);
}
return false;
}
これで吐き出したメールデータを見れば「どの部分を書き替えて送ればいいか」がわかってくると思います。Content-typeも(それに付随するboundaryも)本文パートも元のメールのまま送る必要があります。mb_convert_encodingすらやってはいけません(なのでmb_send_mailじゃなくてmailを使う)。逆に言えばFromやToやSubjectとか書き替えていいですし(mail関数がセットしますしね)Receivedヘッダはいったん削除してもいいですよね。
No.1
- 回答日時:
メールデータの構造を解析して同じように組み立て直すのは無駄が多いと思います。
#たまに真っ当な構造になっていないメールもありますし(苦笑
gdmailを使っていれば、生のメールデータ(テキストデータ)で取得出来ると思います。メールテキストをヘッダ部(最初の「改行のみ」の行まで)とボディ部に分割すれば如何でしょうか?ヘッダ部の中の「From:」や「To:」を「X-org-From:」や「X-org-To:」に置換して、全部をAdditionalHeader(mail関数の第4引数)に渡せばいいのでは?もちろん適当なヘッダを付加して「転送したメール」であることを主張してもいいです(汗
shimix様
早速の回答、ありがとうございます。
質問の送信用phpを使わず、言われたように、
$from_mail = $receiver->header( array('from','mail') , 'none');
$text = mb_convert_encoding(($receiver->text()),"Shift-JIS","auto");
$to ='(送信先)';
$subject = '(件名)';
$message = $text;
$attach = $receiver->attach();//添付ファイル
$message .= $attach ;
$header = "From: $from_mail";
//メール送信
if (mail($to, $subject, $message, $header)) {
echo 'メールが送信されました。';
} else {
echo 'メールの送信に失敗しました。';
}
としたところ、本文、件名、ヘッダーとも転送されるのですが、
添付ファイルが添付されない状態となります。
(転送先で、添付が存在しない状態です)
私のプログラムの書き方が、どこか違うと思いますので、
よろしければ、正しいソースで教えて頂けると幸いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- PHP PostgreSQLからCSV形式でエクスポートする際にカラム内の改行をとる方法 1 2023/02/22 10:05
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
サーバーによってはmb_send_mai...
-
POP Before SMTPでメールを送信...
-
さくらサーバーにて、phpからメ...
-
【初歩?】変数をセットできな...
-
PHPMailerのコードエラーが解決...
-
PHPのif文でその処理を途中で抜...
-
FTPコマンドでディレクトリごと...
-
フォントの色を変えるには?
-
Subversionのリポジトリの削除
-
PHPで`headers already sent`と...
-
「include()」関数の使い方につ...
-
ファイルアップロードの上限を...
-
SELECTの値を保持する
-
UWSCにつきまして
-
VB2008でFTPでのディ...
-
リンク先を隠す方法はないでし...
-
submitボタンの二重送信について
-
PHPの変わった閉じタグの必要性...
-
javamailで220の応答が遅い
-
ある条件に当てはまったときに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
さくらサーバーにて、phpからメ...
-
サーバーによってはmb_send_mai...
-
mb_send_mail関数が利用出来ない
-
【初歩?】変数をセットできな...
-
POSTで送られたアドレスから@以...
-
mb_send_mail でスパム扱いとなる
-
PHPからのメールがこない
-
phpでmb_send_mailを用いてメー...
-
メール送信プログラム
-
mail関数を使った場合のReturn-...
-
mail関数
-
メール送信で文字化け
-
PHPメール送信で文字化け
-
excel VBAでメールを送る方法に...
-
PHPをつかったメール送信時の文...
-
PHPでの文字列のつなぎかた
-
コマンドプロンプト、VBSでの添...
-
ローカル環境でのメール送信
-
phpでのメール転送(添付ファイ...
-
ワードプレス 予約システム
おすすめ情報