• ベストアンサー
  • 困ってます

PEARのmimeDecodeについて

お世話になります 下記スクリプトにてメールをPHPで受け取ることは出来ているのですが、 画像データの処理について教えて頂けないでしょうか? $FromAddress,$Subject,$MailBodyとそれぞれの変数で取得したデータはデータベースに格納出来ています。 しかし、添付されている画像データを取り出してデータベースに格納する所でつまずいています。 // ファイルを保存 $fp = fopen("/tmp/". time() . $type, "w"); $length = strlen($part->body); fwrite($fp,$part->body,$length); fclose($fp); 上記部分で画像データは取得出来ていると思われるのですが、データベースに格納出来るデータに変更するための処理をアドバイス願います。 宜しくお願いします ちなみにPHP4です #PHPファイル########################### /////////////////////////////////// //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=""; }

noname#227352

共感・応援の気持ちを伝えよう!

  • 回答数1
  • 閲覧数151
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.1
  • agunuz
  • ベストアンサー率65% (288/437)

>fwrite($fp,$part->body,$length); これで書き込めているのなら、単に $part->body を使えばいいだけです。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • PEAR の 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=""; }

    • ベストアンサー
    • PHP
  • PEARのmimeDecodeについて

    お世話になっております 受信メールの解析にチャレンジしているのですが、デコメールの処理でつまずいています 下記の記述でメールの本文は取得出来ているのですがデコメール場合は、どのような処理をすればいいのでしょうか? あちこちのサイトを参考にしてみてはいるのですが、自力で答えが導きだせません お手数おかけ致しますが、アドバイスお願い致します 宜しくお願い致します #-- 本文の取得#################################################### 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=""; }

    • 締切済み
    • PHP
  • PEARのmimeDecodeでメール解析をしたい

    レンタルサーバにPEARをインストールし、 mimeDecode.phpを使って、メールを解析したいのですが、 上手くいきません。 下記のサイトを参考にしましたが、やはりできませんでした。 http://d.hatena.ne.jp/makotoworld/20071106/1194309820 http://www.abe-tatsuya.com/web_prog/php/mail2php.php メールを分解するファイル(.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&#65374;&#65374; Notice: Undefined index: to in&#65374;&#65374; と、エラーを吐いています。 これも謎です…。一体、どういうことになっているんでしょうね?!汗 ・パスの書き方に誤りがあり、 正常に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経由でインストールしました。 長くなりましたが、宜しくお願い致します。

    • ベストアンサー
    • PHP
  • Mail_mimeDecodeでメール本文取得

    index.php <form action="mailto:info@hoge.com" method="get" id="join"> <input type="hidden" name="body" value="<?php echo $friend;?>" /> </center></form> empty_mail.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); $MailBody = getbody($mail_data); if (!$MailBody) { print "cannot get MailBody"; // エラー処理 }// $MailBodyを使った処理 function getbody($arg) { if ($arg->ctype_primary == 'multipart') { foreach($arg->parts as $parts) { $ret = getbody($parts); if ($ret) { return $ret; } } } if ($arg->ctype_primary == 'text') { if ($arg->ctype_secondary == 'plain') { if (strtolower($arg->ctype_parameters['charset']) == 'iso-2022-jp') { return mb_convert_encoding($arg->body, "UTF-8", 'JIS'); } else { return $arg->body; } } } return false; } //メールを解析する $decoder = new Mail_mimeDecode($source); $structure = $decoder->decode($params); //送信元を取得する $mail = $structure->headers['from']; $mail = addslashes($mail); $mail = str_replace('"','',$mail); $from = $structure -> headers['from']; $from = mb_decode_mimeheader($from); $from = mb_convert_encoding($from, mb_internal_encoding(),'auto'); if(preg_match( '/<(.*?)>$/' , $from , $match)){ $from = $match[1]; } $from = trim($from); $from = strtolower($from); //送信データを設定する $recipients = $from; $new_from = 'info@hoge.com'; mb_language('ja'); mb_internal_encoding('sjis'); $subject = mb_encode_mimeheader(mb_convert_encoding("登録URL", "JIS", "auto"), "JIS"); $body = "下記のURLをクリックして登録を行ってください http://hoge/hoge.php?". $MailBody . "". session_name()."=". htmlspecialchars(session_id()); と$friendを登録フォーム画面にいくまで情報を維持したいのですが、ご教授お願いします。

    • ベストアンサー
    • PHP
  • 自動返信でのMail_mimeDecode

    //メールソースを読み込む $source = file_get_contents("php://stdin"); if(!$source){ exit(); } $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 = getbody($mail_data); if (!$MailBody) { print "cannot get MailBody"; // エラー処理 }// $MailBodyを使った処理 function getbody($arg) { if ($arg->ctype_primary == 'multipart') { foreach($arg->parts as $parts) { $ret = getbody($parts); if ($ret) { return $ret; } } } if ($arg->ctype_primary == 'text') { if ($arg->ctype_secondary == 'plain') { if (strtolower($arg->ctype_parameters['charset']) == 'iso-2022-jp') { return mb_convert_encoding($arg->body, "UTF-8", 'JIS'); } else { return $arg->body; } } } return false; } //メールを解析する $decoder = new Mail_mimeDecode($source); $structure = $decoder->decode($params); //送信元を取得する $mail = $structure->headers['from']; $mail = addslashes($mail); $mail = str_replace('"','',$mail); $from = $structure -> headers['from']; $from = mb_decode_mimeheader($from); $from = mb_convert_encoding($from, mb_internal_encoding(),'auto'); if(preg_match( '/<(.*?)>$/' , $from , $match)){ $from = $match[1]; } $from = trim($from); $from = strtolower($from); //送信データを設定する $recipients = $from; $new_from = 'get@hoge.com'; mb_language('ja'); mb_internal_encoding('sjis'); $subject = mb_encode_mimeheader(mb_convert_encoding("登録URL", "JIS", "auto"), "JIS"); $body = "下記のURLをクリックして登録を行ってください http://hoge.com/regist.php?". $MailBody . "". session_name()."=". htmlspecialchars(session_id()); とメールを自分のHPに送る際に本文にデータがあるのですが、そのデータを取り出し登録URLに付加し、情報を維持させたいのですが、上記のソースですと$MailBodyに情報がはいっていません。ベテランさん!ご指導、ご教授お願い致します

    • ベストアンサー
    • PHP
  • 文字入れ替え

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } int p, q; for(p = 0; p < line; p++){ for(q = 0; q < line; q++){ if(strcmp(data[p].class_type, data[q].class_type) == 0 && strcmp(data[p].subject, data[q].subject) == 0 && p != q ){ printf("p=%d q=%d\n", p, q); } } } fclose(fp); return 0; } こちらのプログラムは 1,A,山根,音楽//番号、クラス、名前、好きな教科 2,B,本田,美術 3,B,松本,美術 4,A,横野,音楽 というファイルの内容を読み込んでクラスと好きな教科が同じものを 1,A,山根、音楽 4,A,横野、音楽 2,B,本田、美術 3,B,松本、美術のようにソートするプログラムの続きですが ソート方法についてです。 if(strcmp(data[p].class_type, data[q].class_type) == 0 && strcmp(data[p].subject, data[q].subject) == 0 && p != q ){ swap(data[p+1].number, data[q].number; swap(data[p+1].class_type, data[q].class.type); swap(data[p+1].name,data[q].name); swap(data[p+1].subject,data[q].subject); } void swap(char *p, char *q) { char *temp; temp = p; p = q; q= temp; } のように追加してみましたが入れ替えができていません。 どこがまずいのでしょうか?又他にも良い方法があれば教えて下さい。

  • ポインタ

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test.txt","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; // printf("%s", bufG); switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } printf("%s", data[2].subject); fclose(fp); return 0; } このプログラムをベースにしてメモリの無駄を省けるような プログラムに修正したいのですが、 ポインタほんとできなくて困ってます。 教えていただいてメモリを取る位置とかは大体わかりました。 まず構造体のメモリをとります。しかしこのままでは固定長になってるので 構造体を少しいじくりますよね。 構造体の中身なのですが typedef struct{ int number; char *class_type; char *name; char *subject; } my; my *data; にして data = malloc(100); このような形でとります。 文字列の型ですがchar *class_typeのようにポインタで宣言しないと bufGを代入して値を入れるときに型が合いませんので 配列にしないのであればポインタ型宣言でいいと思います。 しかしポインタで宣言してstrcpy(・・)の所を data[line].class_type = bufG にするとエラーはでませんが*strの値が変わる度に data[line].class_typeの値が変動するのでdata[line].class_typeが 国語 とかになったりします。 なんかもうさっぱりわからないんですが どうすればいいのでしょうか? 変換したソースがほしいです。

  • ポインタ(追加質問)

    http://okwave.jp/qa5092628.html の続きです。補足にいれようかとも思いましたが 以前より前の質問は占めたほうがいいと言われつづけてたので 閉めてしまいました。 #include <ctype.h> #include <string.h> #include <stdlib.h> #include <stdio.h> typedef struct{ int number; char *class_type; char *name; char *subject; } my; my *data; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i, non_value = 0; data = malloc(sizeof(my)*100); //最大100人分とる。それを越えたケースは今は考慮しない。ここを変更 if((fp=fopen("test.txt","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: data[line].number=atoi(bufG); //ここを変更 break; case 1: data[line].class_type = malloc(strlen(bufG)+1); //これを追加 strcpy(data[line].class_type, bufG); break; case 2: data[line].name = malloc(strlen(bufG)+1); //これを追加 strcpy(data[line].name, bufG); break; case 3: data[line].subject = malloc(strlen(bufG)+1); //これを追加 strcpy(data[line].subject, bufG); break; } field++; } else{ str++; non_value++; if(non_value == 2){ switch(field){ case 0: data[line].number=' '; //ここを変更 break; case 1: data[line].class_type = malloc(3); //これを追加 strcpy(data[line].class_type, " "); break; case 2: data[line].name = malloc(3); //これを追加 strcpy(data[line].name, " "); break; case 3: data[line].subject = malloc(3); //これを追加 strcpy(data[line].subject, " "); break; } non_value = 0; str++; field++; } } line++; field = 0; } //ここはおまけ for (i =0; i < line;i++){ printf("%d:%s:%s:%s\n", data[i].number,data[i].class_type,data[i].name,data[i].subject); } fclose(fp); return 0; } 前回載せてもらった解答ではcsvファイルに空欄があると 値が代入されなかったのでその機能をつけました。 具体的には,が連続してあると(csvファイルに空欄がある場合1,A,,数学のように,と,の間には何もない)場合半角スペースを入れてます。 この場合例えば1,A,,数学のように名前の欄を空白にするとdata[0].name は半角スペースが入ってますが その次の値、すなわちdata[0].subjectの値がばぐった値になっています。 改善方法を教えて下さい。 もう1点あります。上のソースでは data = malloc(sizeof(my)*100); //最大100人分とる。それを越えたケースは今は考慮しない。ここを変更 とありますがこれを while(fgets(buf,1000,fp) != NULL){ str = buf; data = malloc(sizeof(my)*100); ←このへんに  if(line > 100)){ //メモリ追加処理 } のようにすることは可能ですか?

  • メモリ

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> int check(int a[100], int n); typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } int p, q; int a[100]; int u = 0; for(p = 0; p < line; p++){ for(q = 0; q < line; q++){ if(strcmp(data[p].class_type, data[q].class_type) == 0 && strcmp(data[p].subject, data[q].subject) == 0 && p != q ){ //処理 } } } } fclose(fp); return 0; } 先日文字列入れ替えについてご質問したものですが メモリの取り方についてご質問します。 先日このプログラムにおいて my data[100]と固定してるのはいけないという意見をもらったので メモリを取得しようと思ってるのですが できればdata[i].○○の形でアクセスしたいのでこのままの形は あまりかえたくないです。この場合 while(fgets(buf,1000,fp) !=NULL){ str=buf;     int len = strlen(buf); my *o; o = (my *)calloc( len + 1, sizeof(my *)) while(*str != '\0'){ としてみたのですがこれは実際どうなのでしょうか? NULLは帰ってきてないみたいなので割り当ては出来てるとは思うんですが この一行の文字列の大きさにぴったり合うメモリを割り当てたいのですが ちゃんとなっているか調べる方法を教えて下さい。

  • 配列

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } int p, q; for(p = 0; p < line; p++){ for(q = 0; q < line; q++){ if(strcmp(data[p].class_type, data[q].class_type) == 0 && strcmp(data[p].subject, data[q].subject) == 0 && p != q ){ printf("p=%d q=%d\n", p, q); } } } fclose(fp); return 0; } こちらのプログラムは 1,A,山根,音楽//番号、クラス、名前、好きな教科 2,B,本田,美術 3,B,松本,美術 4,A,横野,音楽 というファイルの内容を読み込んでクラスと好きな教科が同じものを 1,A,山根、音楽 4,A,横野、音楽 2,B,本田、美術 3,B,松本、美術のようにソートするプログラムの途中で 一致する行を表示しようとしている所です。 これをコンパイルした場合 一致しているのは 0行目と3行目 1行目と2行目 2行目と1行目 3行目と0行目と表示され実際には同じ行が含まれています。 このような場合どのように改善すればいいのか教えて下さい。