【最大10000ポイント】当たる!!質問投稿キャンペーン!

レンタルサーバにPEARをインストールし、
mimeDecode.phpを使って、メールを解析したいのですが、
上手くいきません。

下記のサイトを参考にしましたが、やはりできませんでした。
http://d.hatena.ne.jp/makotoworld/20071106/11943 …
http://www.abe-tatsuya.com/web_prog/php/mail2php …

メールを分解するファイル(.php)では、
file_get_contents("php://stdin")のようなカタチで、
メール情報はキャッチできています(確認済みです)が、
それを、

$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);

#-- 本文の取得
$MailBody = $mail_data->body;
$MailBody = mb_convert_encoding($MailBody,"UTF-8","JIS");

としても、取り出せないのです。
(つまり、$MailBody は空っぽのままなのです。)

さらに、

#-- From フィールドの取得
$FromAddress = $mail_data->headers['from'];

#-- To フィールドの取得
$ToAddress = $mail_data->headers['to'];

としている部分では、error_reportingが、

Notice: Undefined index: from in~~
Notice: Undefined index: to in~~

と、エラーを吐いています。
これも謎です…。一体、どういうことになっているんでしょうね?!汗

・パスの書き方に誤りがあり、
正常にPEARにアクセス(利用)できていない?

・そもそも、インストールが怪しい?

・上記の、参考にした2サイトでは、
mimeDecode.phpの扱い方が違うのですが、この違いとは?
これは、PEARのバージョンの新旧の問題?
だとすると、今となっては、
どちらか一方しか使えない、もしくは、両方とも使えない?
つまり、サイトを参考にして書いたコードがそもそも古くて使い物にならない?

・ファイルのパーミッションの問題?(保存形式はEUCとしています)

以上の点が、気になっています。

この事態を打開するためには、どう切り分けながら改善していったらよろしいでしょうか。
どなたかお詳しい方、どうか教えて下さい。

なお、
FFFTPにより、PEARのファイル群が置かれていることは確認しています。
(mimeDecode.phpもあります。)

コードの冒頭は、

#!/usr/local/bin/php

<?php
error_reporting(E_ALL);

としています。

レンタルサーバは、さくらインターネットのスタンダードプランです。
PHPバージョンは、5.2.14。
PEARは、最近、http://pear.php.net/go-pear経由でインストールしました。

長くなりましたが、宜しくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

そういえばお久しぶりでしたね。



とりあえず、
file_get_contents("php://stdin");
が、取得できているのであれば、
メール取得部のプログラムを、

<?php

$log = file_get_contents('php://stdin');

file_put_contents('log_'.time().'.txt', $log);

?>
とか、適当にメールを書き出す処理だけかけておいて、
ローカルなど適当な環境で、そのファイルをデコード処理するプログラムを書いてチェックしてみてはどうでしょう。

基本的にパーサとかといったものは、泥臭いコードが書かれていたりするので、単純に受信した形式のメールだと
処理不能となって、こけている可能性があります。

いくつかのメーラ、自宅のPCのメーラーや、GmailなどWebメールとかなど、いくつかのクライアントで試したりしてみると
良いかもしれませんね。

また、mimeDecodeに既知のバグがないかを調べてみるのも良いかもしれません。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

>そういえばお久しぶりでしたね。

当時、私はホゲホゲさんにかなりご迷惑をお掛けしていたと思っていましたので、、
要注意人物として記憶されているかと思っていましたが、
実際には、そうでもなかったみたいですね。笑
嬉しいような寂しいような。笑

さて、このメールデコードプログラムmimeDecodeについてですが、
ホゲホゲさんのお話から、万能というわけではないんだな、ということが分かりました。

どんなメールに対しても、器用にメール情報を分解し、
本文の抽出などを手軽に行えるものと過信していました。

実際には、
送るメールの種類によって、パースできたりできなかったりするような類のプログラムだったようで、
このことに対しては、PEARを万能と思いこんでいた私には驚きでした。

コードの中身は実は泥臭いということを知りましたので、
であれば、自作する道を選びますw
というか、今回の場合、自作した方が早いケースだったので、
最初からしておけば良かったなと後悔していますw
実際には、もう9割方、完成しちゃっているのですが…。

>mimeDecodeに既知のバグがないかを調べてみるのも良いかも

いやぁ、そんな意欲は、ありませぬ。苦笑

今回も、どうもありがとうございました。
自作によるメールパーサにつまづきましたら、
先ほど教わりました POP-Qdreciever なるものに手を出してみたいと思います。
もうPEARはこりごりです。苦笑

お礼日時:2010/11/27 01:42

■取得できない件


ソース確認してみましたが、
$mail_data変数に格納されるものは、普通のstdClassです。
一度var_dumpしてみて中に情報含まれるのか確認してみてください。

また、どうもそもそも不正な値が含まれていたりした場合、エラーメッセージ等でないでスルーするような挙動をするっぽいので
一度実際にmimeDecode.phpの中身確認して、必要であればライブラリにprint等書きこんで動きをチェックとかしたほうが早いかもしれません。

■decodeメソッドの呼び出し方に関して
Mail_mimeDecodeのdecodeメソッド呼び出しは、静的に呼び出しても、インスタンスつくってから呼び出しても同じ結果が返ります。

静的に呼び出せばデコード後のインスタンスをunsetする手間を省けるので楽っていう所ではないでしょうか。

■その他
http://hal456.net/
こちらの、POP-Qdrecieverを使ったほうが楽出来るかもしれません。
    • good
    • 0
この回答へのお礼

お久しぶりです、hogehogeさん。
またお話しできて嬉しいです。

さて、「一度var_dumpしてみて中に情報含まれるのか確認」の件ですが、
var_dump($mail_data)の値を確認するのは、実はちょっと面倒だったりします。
なぜなら、
file_get_contents("php://stdin"); は、ご存知の通り、
メールを送ってみることで生成されるデータだからです。
で、メールを送ってみて、その後、
どうやってvar_dump($mail_data)の値を確認したら良いか、
を考え、
$mail_content = var_dump($mail_data);として、
$mail_contentの値を、自分のメールアドレスに送って、
そのメール本文から値を確認しようかとも思ったのですが、
なぜかはわかりませんが、
var_dump();の値は、メールでは確認できなかったため、

それでは!ということで、

file_get_contents("php://stdin"); をせずに、
file_get_contents("php://stdin"); で受け取るはずの値(ここでは、例として、'hogehoge~~~')を、
コピペして、それを

$mail_get_contents = 'hogehoge~~~';
として手動コピペし、

その値に対し、
echo var_dump($mail_get_contents);
として、web上で確認してみました。

で、その結果が、

object(stdClass)#2 (4) { ["headers"]=> array(0) { } ["ctype_primary"]=> string(4) "text" ["ctype_secondary"]=> string(5) "plain" ["body"]=> string(0) "" }

となります。

>エラーメッセージ等でないでスルーするような挙動をするっぽい

これでは、デバグしづらいですよね…。汗

>一度実際にmimeDecode.phpの中身確認して、必要であればライブラリにprint等書きこんで動きをチェックとかしたほうが早いかも

なんだか繁雑な作業になりそうですね。
それならばいっそのこと、自分で正規表現で抽出した方が早そうです。苦笑
手早く、容易に使えるだろうとのことでPEARに手を出したというのに、
これでは本末転倒ですw

>POP-Qdrecieverを使ったほうが楽出来るかも

こちら、ちょっと調べてみますね。
相変わらず、分かりやすく、為になる回答をありがとうございます。
また何か分かることがありましたら、教えて下さい。

お礼日時:2010/11/27 00:51

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPEAR の Mail_mimeDecodeで

お世話になります
下記スクリプトにてメールを受信してDBに格納しようと思っています
DBに格納後、メールサーバからメールを消したいのですが、メールボックスを空にするためにの処理を教えて頂けないでしょうか?

宜しくお願いいたします。



///////////////////////////////////
//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 フィールドの取得
$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);
// jpg,gif,png以外の画像形式は受け付けない
if($type != "jpeg" and $type != "jpg" and $type != "gif" and $type != "png"){
continue;
}
// ファイルを保存
/*
$fp = fopen("/tmp/". time() . $type, "w");
$length = strlen($part->body);
fwrite($fp,$part->body,$length);
fclose($fp);
*/
break;
}
}
break;
default:
$MailBody="";
}

お世話になります
下記スクリプトにてメールを受信してDBに格納しようと思っています
DBに格納後、メールサーバからメールを消したいのですが、メールボックスを空にするためにの処理を教えて頂けないでしょうか?

宜しくお願いいたします。



///////////////////////////////////
//PEARのパスを設定
require_once 'Mail/mimeDecode.php';

#-- メールデータの取得
$params['include_bodies'] =true;
$params['decode_bodies'] =true;
$params['decode_headers'] =true;
$params['input'] = file_get_contents...続きを読む

Aベストアンサー

>メールボックスを空にするためにの処理

メールを送るのはPEAR::Mailですが受け取るのはPEAR::Net_pop3ですね

http://pear.php.net/manual/ja/package.networking.net-pop3.php

deleteMsg() で削除ができます

Qillegal string offset

php5.3では動いていたプログラムをphp 5.4 で動かしたらwarning illegal string offsetが出て困っています。以下のプログラムでwarningが出ないようにするにはどのようにコーディングすればよいのでしょうか?


$a = array('exists' => 'foo');
if ($a['exists']['non_existent']) {
print 1;
}
print 2;
exit;

Aベストアンサー

isset()を使えばいいと思います

Qsyntax error, unexpected '}' というエラーの対処法

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" maxlength="3" />
<input type="sbumit" value=回答" />
</form>
<hr />
<?php
session_start();
if(is_null($_SESSION['answer'])){
mt_stand(microtime()*1000000);
$_SESSION['answer']=mt_rand(1,100);
$_SESSION['game_cnt']=0;
}
if($_POST['answer']!=""){
$_SESSION['game_cnt']++;
if($_session['answer']==$_POST['answer']){
print("おめでとうございます".
$_SESSION['game_cnt']."回で正解しました!");
session_destroy();
}else{
if($_SESSION['answer']>$_POST['answer']){
print("もう少し大きいです。");
}else
print("もう少し小さいです。");
}
}
}
?>
</body>
</html>
それとこの間違えたところをなおしたあとはいつもコンピュータを再起動しないと修正したところが適用されないのですがほかに方法はないですか?基本的な質問ですいません。

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" max...続きを読む

Aベストアンサー

print("もう少し大きいです。");
}else
print("もう少し小さいです。");
のelseの後に{がないようですが、大丈夫でしょうか?

Qphpでのメール転送(添付ファイルつき)について

目的:
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 'メールの送信に失敗しました。';
}

?>

以上、よろしくお願いします

目的:
phpにて、添付付きメールを、件名だけ変更して、添付ファイルごと外部へ転送する。

現在、メール受信したものを、mysqlに保存(UID、件名、送信元メールアドレス(一致したものを、指定の件名に変更)、送信日、受信日、本文)、
添付ファイルはサーバー上に保存し、

メール送信時に、サーバー上に保存した添付ファイルとmysqlのデータを読み込み、送信しています。
(添付ファイルは、定期的に削除)

これを、もっと簡潔に出来ないでしょうか。
サーバー上に添付ファイルを残さないで済み、
未受信のメ...続きを読む

Aベストアンサー

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処理なども自前で
}

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"...続きを読む

QMySQL5.1.14で空白を入れるとエラーになる

MySQL5.1.14をインストールをしたところ、4.1で動いていたプログラムが軒並みエラーストップ。
どうも、空白を入れるとエラーになるようで、5.1へ移行出来なくて困っています。どなたかご教授をお願いします。

環境は
Windows2000Pro
MySQL 5.1.14-beta

サンプルのテーブルは
drop table if exists addressbook;
CREATE TABLE addressbook(
id smallint(4) UNSIGNED NOT NULL auto_increment,
name1 varchar(20) default NULL,
birthday date default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=sjis;

INSERT INTO addressbook VALUES
('','名前1','2006-12-22'),
('','','');
で次のエラーが出る。
ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1

MySQL5.1.14をインストールをしたところ、4.1で動いていたプログラムが軒並みエラーストップ。
どうも、空白を入れるとエラーになるようで、5.1へ移行出来なくて困っています。どなたかご教授をお願いします。

環境は
Windows2000Pro
MySQL 5.1.14-beta

サンプルのテーブルは
drop table if exists addressbook;
CREATE TABLE addressbook(
id smallint(4) UNSIGNED NOT NULL auto_increment,
name1 varchar(20) default NULL,
birthday date default NULL,
PRIMARY KEY (...続きを読む

Aベストアンサー

なるほど、そういう質問でしたか。失礼しました。

調べてみましたけど、ちょっとムリそうでしたねぇ。

エラーの内容からすると、integerに空行はinsertできない旨ですよね。
となると、数値フィールドに''をinsertしたら、NULLと見なすパラメータ等のオプションを探すしかないわけです。
ネットで調べる程度では、わかりませんでした。


人気Q&Aランキング