質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • PHP

    19850questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

メールの内容を取得してPHPの処理をする

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,495
退会済みユーザー

退会済みユーザー

メールの受信をトリガーとしてPHPプログラムを起動し、返信するというものを作っています。
メールの本文を取得し、そこに対して処理を書いているので、その処理結果を本文として返すと空メールのような状態で返ってきてしまいます。

初心者で調べながらの作業ですが、なかなか粘っても解決出来そうになく、質問させて頂きます。

$path = '/home/アカウント名/pear/PEAR/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once '/home/アカウント名/www/pear/PEAR/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";
if (!$params['input']) {// 読み込み失敗
   exit();
}
$structure = Mail_mimeDecode::decode($params);
$mail = $structure->headers['from'];
$mail = addslashes($mail);
$mail = str_replace('"','',$mail);
$mail = preg_replace('/(^.*<|>$)/', '', $mail);
$MailBody = mb_convert_encoding($structure->body,
mb_internal_encoding(), "UTF-8");

// ここに本文を受け取った後の処理

$from = 'hoge@hoge.com';
$head = "From: $from\n";
$subject = 'メールテスト';
$body = $MailBody;
    
// メール送信
mb_language('japanese');
mb_internal_encoding('UTF-8');
mb_send_mail($mail, $subject, $body, $head, $from);

このような記述でメールの受信をしたらその本文を$MailBodyに格納して、メールを送信元に送信するというところまでは無事に辿り着いたのですが。。。

ここに本文を受け取った後の処理の所に、

$values = preg_replace("/( | )/", "", $MailBody);
$array = explode("\n", $values); // とりあえず行に分割
$array = array_map('trim', $array); // 各要素をtrim()にかける
$array = array_filter($array, 'strlen'); // 文字数が0のやつを取り除く
$array = array_values($array); // 連番振り直し

foreach($array as $value) { // 配列の値を取り出す
  if(preg_match('/^名前/', $value)) { //もし値の初めに名前がつく値があったら
      $hogehoge = preg_replace('/名前/', '', $value); // 名前を削除して残った文字列を格納
   }
}

$from = 'hoge@hoge.com';
$head = "From: $from\n";
$subject = 'メールテスト';
$body = $hogehoge;
    
// メール送信
mb_language('japanese');
mb_internal_encoding('UTF-8');
mb_send_mail($mail, $subject, $body, $head, $from);

上記のように、メールを受け取ったら1行ずつ配列に格納して取り出し、処理を行っていきたいです。

送られてくる本文の例)
名前テスト太郎
年齢15
生年月日2000#2#20

なので、$hogehogeにはテスト太郎が入って、それを返信の本文として使用したいと思いこういった記述になりました。
しかし、実際に動かすと空メールが返ってくるだけで、$hogehogeには何も値がないこと?になってしまっています。

どなたかご教授頂けますと幸いです。
宜しく御願い致します。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

送信されたメールの文字コードとソースや内部処理の文字コードが異なる可能性もありますし、先頭に「名前」が来てないのかも知れませんし、一旦全て書き出してみるのはどうでしょう?
$hogehoge = "文字化けチェックの一行目\n";
foreach($array as $value) { // 配列の値を取り出す
  $hogehoge = $hogehoge . $value . "\n";
  if(preg_match('/^名前/', $value)) {
      $hogehoge = $hogehoge . ":: " . preg_replace('/名前/', '', $value)  . "\n";
   }
}
※検証してないのでエラーとかあるかもしれません。
旨く動けば、メールを全て書き出しつつ、名前の行の下に「:: 」で始まる行が追加されているはずです。
一行目だけ化けてて他が問題無しなら、PHPファイルの文字コードに問題あるのかも知れません。
メール本文全部文字化けしていたり、「名前」が先頭に来ているのに「:: 」の行だけ無い場合は、文字コードの問題か、正規表現がちゃんと動いていないか。
1行も出ていない場合は、配列に入れて整形してる部分に問題があるのかも。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/04 21:36

    ありがとうございます!!
    文字化けチェックの一行目は、何を入れたらいいんでしょうか?><

    キャンセル

  • 2015/10/04 21:41

    日本語なら何でもいいと思います。(例示したままでも)
    もし、PHPのコードがshift-jisなどで記述されていたら
    $hogehoge = "文字化けチェックの一行目\n";
    この1行目がshift-jisで、その後に追加されるメール本文がutf-8ってことになり、
    $hogehoge内にshift-jisとutf-8が混在します。
    それを強引にutf-8に変換してメール送信すると、1行目が化ける可能性が高いので、そのチェック用です。
    この場合「preg_match('/^名前/', $value)」このソース上の「名前」もshift-jisなので、utf-8の「名前」にHITしない可能性もあると思います。

    キャンセル

  • 2015/10/04 21:47

    ご返信ありがとうございます。
    メールが返ってきました。1行目は「文字化けチェックの一行目」と文字化けせずに出てきました。他の文字も文字化け箇所は見当たりませんでした。

    ですが、「名前」が先頭に来ているのに「::」の行は見当たりません。(これは文字コードの問題なのでしょうか。)
    また、配列の個数分メール本文が繰り返してしまっています。。。

    キャンセル

  • 2015/10/04 21:55 編集

    >>また、配列の個数分メール本文が繰り返してしまっています。。。
    ということは、この行が機能してないっぽいですね。
      $array = explode("\n", $values); // とりあえず行に分割

    foreach($array as $value)
    これのvalueに一行だけでなく、全行入ってしまってるっぽい?

    キャンセル

  • 2015/10/04 21:58

    改行コードが異なるからなんですかね。。。

    キャンセル

  • 2015/10/04 22:00

    $body = $array[0];

    と指定すると「名前」という返信が確認出来たので、行に分割はできてそうでした!

    キャンセル

  • 2015/10/04 22:02

    うん? $array = array_values($array); // 連番振り直し
    これのせいでは?
    http://php.quus.net/array/array_values.php

    キャンセル

  • 2015/10/04 22:11 編集

    すみません。↑は問題なさそうです。
    $str = "一行目\n名前 太郎\n3行目\n\n";
    $array = explode("\n", $str);
    $array = array_map('trim', $array); // 各要素をtrim()にかける
    $array = array_filter($array, 'strlen'); // 文字数が0のやつを取り除く
    $array = array_values($array);

    $hogehoge = "aa";
    foreach($array as $value) { // 配列の値を取り出す
    if(preg_match('/^名前/', $value)) { //もし値の初めに名前がつく値があったら
    $hogehoge = preg_replace('/名前/', '', $value); // 名前を削除して残った文字列を格納
    }
    }
    echo $hogehoge; // 太郎

    このコードを動かしてみたら期待通りの結果が得られたので、コードそのものには問題なさそうなんですが

    キャンセル

  • 2015/10/04 22:19 編集

    あ、ごめんなさい。私が書いたコードに問題がありました。
    配列の個数分返ってきてたのはこのせいです。失礼しました。
    $hogehoge = $hogehoge . $values . "\n";
    これ
    $hogehoge = $hogehoge . $value . "\n";

    $values -> $value

    キャンセル

  • 2015/10/04 22:22

    ご検証頂きましてありがとうございます!
    コードそのものには問題なさそうであれば、何が原因なんでしょう...^^;

    キャンセル

  • 2015/10/04 22:26

    if(preg_match('/^名前/', $value))
    これにHITしないんでしょうね。
    メール本文の「名前」のところ「name」に変更できるならそうして
    if(preg_match('/^name/', $value)) コードのほうもこう変えて
    それでもし期待通りの結果が来たら、文字コードのせいかもですね。
    確認ですが、phpファイルはutf-8で保存されていますか?
    またphpの実行コードはutf-8になっていますでしょうか?

    キャンセル

  • 2015/10/04 22:34

    $hogehoge = "文字化けチェックの一行目\n";
    foreach($array as $value) { // 配列の値を取り出す
    $hogehoge = $hogehoge . $values . "\n";
    if(preg_match('/^名前/', $value)) {
    $hogehoge = $hogehoge . ":: " . preg_replace('/名前/', '', $value) . "\n";
    }
    }

    $hogehoge = "文字化けチェックの一行目\n";
    foreach($array as $value) { // 配列の値を取り出す
    $hogehoge = $hogehoge . $value . "\n";
    $values -> $value;
    if(preg_match('/^名前/', $value)) {
    $hogehoge = $hogehoge . ":: " . preg_replace('/名前/', '', $value) . "\n";
    }
    }

    こういうことでしょうか?

    キャンセル

  • 2015/10/04 22:36

    はい。それで、「配列の個数分メール本文が繰り返してしまって」は解決すると思います。
    「:: 」から始まる行は無いままでしょう。
    if(preg_match('/^名前/', $value))
    これにうまくHITしていないように思います。

    キャンセル

  • 2015/10/04 22:42

    nameに変更してみたら「::」から始まる行が出てきました!

    キャンセル

  • 2015/10/04 22:46

    ということは、PHPを記述しているファイルか内部処理の文字コードと、メールを変換した文字コードが一致していない可能性が高いように思います。
    $MailBody = mb_convert_encoding($structure->body,
    mb_internal_encoding(), "UTF-8");
    この$mailBody内の「名前」と
    PHPのif(preg_match('/^名前/', $value))この「名前」のバイナリ値が異なるため一致しないんだと推測

    キャンセル

  • 2015/10/04 22:47

    なるほどです!
    文字コードの不一致によるものだったんですね。

    >>phpファイルはutf-8で保存されていますか?
    →これはmb_internal_encoding('UTF-8');この指定が入っているかってことでしょうか?

    キャンセル

  • 2015/10/04 23:04 編集

    PHPを何らかのエディタで編集していると思いますが、そのファイルの文字コードの話です。エディタにもよりますが、大抵保存時に文字コードを選択できると思います。
    .phpファイルが仮にshift-jisなら、その中も日本語もshift-jisなので…
    ただ他の全てのphpがshift-jisなのに、そのファイルだけutf-8ってのも問題なので、それが原因だったとしても対応は別の方法でやったほうがいいと思います。

    例えばもしshift-jisなんだったとしたら
    $s = mb_convert_encoding("名前", "UTF-8", "shift-jis");
    if(preg_match('/^'.$s.'/', $value))
    こんな感じで動くかも知れません
    ただまぁPHP側がshift-jisで無くなったら動かなくなりますので、移植性は凄く悪くなりますね。

    キャンセル

  • 2015/10/04 23:15

    $MailBody = mb_convert_encoding($structure->body,
    mb_internal_encoding(), "UTF-8");

    この取得するところの文字コードはこのままで大丈夫でしょうか?

    キャンセル

  • 2015/10/04 23:19 編集

    >> $MailBody = mb_convert_encoding($structure->body,mb_internal_encoding(), "UTF-8");
    あーそうか、これってひょっとして一旦EUC-JPに変換してます? 
    mb_internal_encoding()は内部処理コードを参照するようです -> http://phpjp.com/mb_internal_encoding.htm
    この行為に意味があるのかはわかりませんが、とりあえず、内部処理コードとPHPファイルの文字コードが一致してない可能性が高そうです。
    ※元がutf-8みたいだし不要ならこの行外しちゃってもいいのかも?その辺りは解りません

    そのまま残す場合はこんな感じでしょうか
    $MailBody = mb_convert_encoding($str, mb_internal_encoding(),'UTF-8');
    $s = mb_convert_encoding("/^名前/", mb_internal_encoding());
    .....
    if(preg_match($s, $value)) {

    キャンセル

  • 2015/10/05 00:44

    PHPのファイルの文字コードはUTF-8でした!

    キャンセル

  • 2015/10/05 00:52

    あれ、、
    $MailBody = mb_convert_encoding($structure->body, "UTF-8", "jis");
    この記述に変えてみたら行けました!!!

    キャンセル

  • 2015/10/05 02:36

    jis はバグの温床、sjis-win を使うべき。

    キャンセル

0

$hogehoge = preg_replace('/名前/', '', $value); // 名前を削除して残った文字列を格納

$hogehoge .= preg_replace('/名前/', '', $value);

文字列が連結されていない。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/04 22:35

    回答ありがとうございます!
    foreachの前に$hogehoge=""という記述はいりますでしょうか?

    キャンセル

  • 2015/10/04 22:38

    あったほうがいいですよね。Undefined variable ... が出るだろうから。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    19850questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。