33

生の電子メールをパーツに解析するためにPHPコードを使用するのに適した/機能する/簡単なものを探しています。

私はいくつかのブルートフォースソリューションを作成しましたが、毎回、1つの小さな変更/ヘッダー/スペース/何かが発生し、パーサー全体が失敗し、プロジェクトが崩壊します。

そして、PEAR / PECLを指摘する前に、実際のコードが必要です。私のホストには厄介な設定などがありますが、.soを正しくビルドすることはできません。.soを作成したとしても、path / environment / php.iniの違いによって、常に使用できるとは限りません(apache、cron、CLI)。

ああ、最後にもう1つ、私は生の電子メールテキストを解析しています。POP3ではなく、IMAPではありません。.qmail電子メールリダイレクトを介してPHPスクリプトにパイプされています。

私はSOFが私のためにそれを書くことを期待していません、私はそれを「正しく」行うためのいくつかのヒント/出発点を探しています。これは、私が知っている「ホイール」の問題の1つです。

4

15 に答える 15

23

最後に何になりたいですか?本文、件名、送信者、添付ファイル?メールの形式を理解するには、 RFC2822を使用する必要がありますが、整形式の電子メールの最も簡単なルールは次のとおりです。

HEADERS\n
\n
BODY

つまり、最初の空白行(二重改行)は、HEADERSとBODYの間の区切り文字です。HEADERは次のようになります。

HSTRING:HTEXT

HSTRINGは常に行の先頭から始まり、空白やコロンは含まれません。HTEXTには、改行文字の後に空白が続く限り、改行を含むさまざまなテキストを含めることができます。

「BODY」は、実際には最初の二重改行に続くすべてのデータです。(SMTP経由でメールを送信する場合はさまざまなルールがありますが、パイプを介してメールを処理する場合は、それについて心配する必要はありません)。

したがって、1982年頃のRFC822の用語では、電子メールは次のようになります。

HEADER: HEADER TEXT
HEADER: MORE HEADER TEXT
  INCLUDING A LINE CONTINUATION
HEADER: LAST HEADER

THIS IS ANY
ARBITRARY DATA
(FOR THE MOST PART)

しかし、最近のほとんどの電子メールはそれよりも複雑です。ヘッダーは、charsetsやRFC2047 mimeワード、または私が今考えていない他の多くのもののためにエンコードすることができます。最近のボディは、意味のあるものにしたい場合に、独自のコードをロールするのが非常に困難です。MUAによって生成されるほとんどすべての電子メールはMIMEエンコードされます。これは、uuencodeされたテキスト、html、uuencodeされたExcelスプレッドシートの場合があります。

これが、非常に基本的な電子メールのバケットのいくつかを理解するためのフレームワークを提供するのに役立つことを願っています。あなたがデータで何をしようとしているのかについてより多くの背景を提供すれば、私(または他の誰か)はより良い方向性を提供できるかもしれません。

于 2008-08-16T02:18:11.893 に答える
19

Plancake PHP メール パーサーをお試しください: https://github.com/plancake/official-library-php-email-parser

私は自分のプロジェクトにそれを使用しました。うまく機能します。これは 1 つのクラスであり、オープン ソースです。

于 2011-05-15T21:56:52.790 に答える
3

試すことができる Mailparse 関数があります: http://php.net/manual/en/book.mailparse.php、ただし、デフォルトの php conf にはありません。

于 2010-11-05T14:36:40.127 に答える
2

Pear lib Mail_mimeDecode はプレーンな PHP で書かれており、ここで確認できます: Mail_mimeDecode ソース

于 2011-11-07T20:49:34.487 に答える
2

このhttps://github.com/zbateson/MailMimeParserは私にとってはうまくいき、mailparse 拡張は必要ありません。

<?php
echo $message->getHeaderValue('from');          // user@example.com
echo $message
    ->getHeader('from')
    ->getPersonName();                          // Person Name
echo $message->getHeaderValue('subject');       // The email's subject

echo $message->getTextContent();                // or getHtmlContent
于 2016-11-23T12:34:43.630 に答える
1

おそらく、独自のMIMEパーサーを作成するのはそれほど楽しいことではないでしょう。「過剰に開発されたメール処理パッケージ」を見つけた理由は、MIMEが非常に複雑なルール/フォーマット/エンコーディングのセットであるためです。MIME部分は再帰的である可能性があり、これは楽しみの一部です。最善の策は、可能な限り最高のMIMEハンドラーを記述し、メッセージを解析し、text/plainまたはtext/html以外のすべてを破棄してから、着信文字列のコマンドの前にCOMMAND:などを付けることです。あなたが泥の中でそれを見つけることができるように。このようなルールから始める場合は、新しいプロバイダーを処理する可能性は十分にありますが、新しいプロバイダーが登場した場合(または、現在のプロバイダーがメッセージングアーキテクチャを変更することを選択した場合)を微調整する準備ができているはずです。

于 2008-08-16T16:06:14.577 に答える
1

I'm not sure if this will be of help to you - hope so - but it will surely help others interested in finding out more about email. Marcus Bointon did one of the best presentations entitled "Mail() and life after Mail()" at the PHP London conference in March this year and the slides and MP3 are online. He speaks with some authority, having worked extensively with email and PHP at a deep level.

My perception is that you are in for a world of pain trying to write a truly generic parser.

EDIT - The files seem to have been removed on the PHP London site; found the slides on Marcus' own site: Part 1 Part 2 Couldn't see the MP3 anywhere though

于 2008-08-16T18:19:41.810 に答える
1

PHP で電子メールを解析することは、不可能な作業ではありません。つまり、それを行うためにエンジニアのチームは必要ありません。それは個人として達成可能です。私が見つけた最も困難な部分は、IMAP BODYSTRUCTURE の結果を解析するための FSM を作成することでした。インターネットのどこにもこれを見たことがなかったので、自分で書きました。私のルーチンは基本的に、コマンド出力からネストされた配列の配列を作成します。配列内の深さは、検索を実行するために必要な部品番号にほぼ対応しています。そのため、ネストされた MIME 構造を非常に適切に処理します。

問題は、PHP のデフォルトの imap_* 関数があまり粒度を提供しないことです...そのため、IMAP ポートへのソケットを開き、必要な情報を送信および取得する関数を作成する必要がありました (IMAP FETCH 1 BODY.PEEK[1.2]たとえば)、RFC ドキュメントを参照する必要があります。

データのエンコーディング (quoted-printable、base64、7 ビット、8 ビットなど)、メッセージの長さ、コンテンツ タイプなどはすべて提供されます。添付ファイル、テキスト、html など。すべてのフィールドが常に 100% 実装されているわけではないため、メール サーバーのニュアンスも把握する必要がある場合があります。

宝石はFSMです... Comp Sciのバックグラウンドがある場合、これを作成するのは本当に楽しいかもしれません(重要なのは、ブラケットが通常の文法ではないということです;)); そうしないと、従来の方法を使用すると、苦労したり、コードが醜くなったりします。また、時間も必要です!

お役に立てれば!

于 2010-11-20T20:49:47.417 に答える
0

ええ、そのrfcと他のいくつかの基本的なチュートリアルに基づいて、基本的なパーサーを書くことができました。しかし、私を台無しにし続けるのは、マルチパート MIME のネストされた境界です。

私の携帯電話から送信された MMS (SMS ではない) メッセージは単なる標準的なメールであることがわかったので、受信メールを読み取り、送信元をチェックし (携帯電話からのみ許可する)、本文部分を使用して別の方法で実行するシステムを使用しています。私のサーバー上のコマンド。電子メールによるリモコンのようなものです。

システムは画像を送信するように設計されているため、さまざまにエンコードされた部分がたくさんあります。mms.smil.txt 部分、text/plain (役に立たない、「これは html メッセージです」と言うだけです)、application/smil 部分 (電話が拾う部分)、text/html 部分携帯電話会社の広告、メッセージ、すべて html でラップ、最後にプレーン メッセージ (私が使用する部分) を含むテキスト ファイルの添付ファイル (メッセージに添付ファイルとして画像を挿入すると、添付ファイル 1、base64 でエンコードされている場合、テキスト部分は添付ファイル 2 として添付されます)

私は自分のキャリアからの正確なメール形式で動作させましたが、他の誰かの電話からのメッセージをそれを通して走らせたとき、それは悲惨な方法でたくさん失敗しました.

この電話 - >メール - >解析 - >コマンドシステムを拡張したい他のプロジェクトがありますが、メールからさまざまな部分を取り出して使用するために、安定した/堅実な/汎用パーサーが必要です。

私の最終目標は、生のパイプされたメールをフィードできる関数を用意し、ヘッダー var:val ペアの連想サブ配列を含む大きな配列と、文字列全体としての本文用の配列を取得することです。

これを検索すればするほど、同じものを見つけます。メールに関連する太陽の下ですべてを行う巨大な開発されすぎたメール処理パッケージ、または役に立たない (このプロジェクトでは) チュートリアル。

私は弾丸を噛んで、自分自身で何かを注意深く書かなければならないと思います.

于 2008-08-16T05:09:11.907 に答える
0

このライブラリは非常にうまく機能します:

http://www.phpclasses.org/package/3169-PHP-Decode-MIME-e-mail-messages.html

于 2011-11-08T21:27:33.653 に答える
0

同じ問題に遭遇したので、次のクラスを書きました: Email_Parser. 生のメールを受け取り、素敵なオブジェクトに変換します。

PEAR Mail_mimeDecode が必要ですが、WHM またはコマンド ラインから簡単にインストールできます。

ここから入手してください: https://github.com/optimumweb/php-email-reader-parser

于 2015-10-23T21:47:40.823 に答える
0

Docker コンテナーからこれを実行しようとしている場合は、ビルド時に PEAR を使用して Mail と Mail_mimeDecode をインストールします。

FROM php:7.4-apache
WORKDIR /var/www/html
EXPOSE 80
WORKDIR /var/www
RUN chown -R www-data html
RUN docker-php-ext-install mysqli
RUN pear install --alldeps mail
RUN pear install Mail_mimeDecode

次に、PHP コードでは、次のようになります。

<?php

require_once "/usr/local/lib/php/Mail.php";
require_once "/usr/local/lib/php/Mail/mimeDecode.php";

$mailfiles = ['/var/www/mail/mailFile1','/var/www/mail/mailFile2'];

foreach($mailfiles as $filename){
    $theFile = fopen($filename, "r") or die("Unable to open file!");
    $rawEmail = fread($theFile, filesize($filename));
    fclose($theFile);

    $args = [];
    $args['include_bodies'] = true;
    $args['decode_bodies'] = FALSE;
    $args['decode_headers'] = FALSE;
    $objMail = new Mail_mimeDecode($rawEmail);
    $return = $objMail->decode($args);

    if (PEAR::isError($return)) {
        echo("<p>" . $return->getMessage() . "</p>");
        var_dump($return);
    } else {
        //echo("No error in PEAR::isError(return)");
    }

    if($return->body){
        $decoded = base64_decode($return->body, true);
        var_dump($decoded);
    }//end if(body)

}//end foreach(mailfiles as file)


?>
于 2021-06-10T15:06:19.537 に答える