質問
10分ごとに受信トレイをチェックするCron'ed PHPスクリプトがあります。このスクリプトの目的は、私たちが提供するSMS通知サービスの「停止するために停止する」機能を処理することです。スクリプトが電子メールの先頭に「停止」という単語があるメールを見つけた場合、通知データベースからユーザーを削除します。
私たちのベースをカバーするために、上記の基準を満たしていないメールを、数人が1時間ごとに受け取ってチェックする別の電子メールアドレス(これはエイリアス)に転送されます。ただし、このPHPスクリプトからメールの転送に問題が発生しています。
方法を知る mail
PHPの機能は、郵送する前にヘッダーを再挿入する必要があることは明らかです。ただし、MIMEマルチパートメールは、障壁やbase64エンコードされた添付ファイルを含む、常にテキストの衣装として送信されます。
誰かが電子メールメッセージを受け取り、PHPスクリプトを使用して適切に転送する簡単な方法を知っていますか?
PHP 5に組み込まれたネイティブIMAP関数を使用しています。また、Pear Mailモジュールにもアクセスできます。ただし、Googleを検索することで、同様のタスクを行っている例や人々が見つけることができませんでした。
解決
私はこの方法をずっと前にコーディングして、IMAPを使用して適切な部品に電子メールメッセージを解析するためにコードしました。
function Message_Parse($id)
{
if (is_resource($this->connection))
{
$result = array
(
'text' => null,
'html' => null,
'attachments' => array(),
);
$structure = imap_fetchstructure($this->connection, $id, FT_UID);
if (array_key_exists('parts', $structure))
{
foreach ($structure->parts as $key => $part)
{
if (($part->type >= 2) || (($part->ifdisposition == 1) && ($part->disposition == 'ATTACHMENT')))
{
$filename = null;
if ($part->ifparameters == 1)
{
$total_parameters = count($part->parameters);
for ($i = 0; $i < $total_parameters; $i++)
{
if (($part->parameters[$i]->attribute == 'NAME') || ($part->parameters[$i]->attribute == 'FILENAME'))
{
$filename = $part->parameters[$i]->value;
break;
}
}
if (is_null($filename))
{
if ($part->ifdparameters == 1)
{
$total_dparameters = count($part->dparameters);
for ($i = 0; $i < $total_dparameters; $i++)
{
if (($part->dparameters[$i]->attribute == 'NAME') || ($part->dparameters[$i]->attribute == 'FILENAME'))
{
$filename = $part->dparameters[$i]->value;
break;
}
}
}
}
}
$result['attachments'][] = array
(
'filename' => $filename,
'content' => str_replace(array("\r", "\n"), '', trim(imap_fetchbody($this->connection, $id, ($key + 1), FT_UID))),
);
}
else
{
if ($part->subtype == 'PLAIN')
{
$result['text'] = imap_fetchbody($this->connection, $id, ($key + 1), FT_UID);
}
else if ($part->subtype == 'HTML')
{
$result['html'] = imap_fetchbody($this->connection, $id, ($key + 1), FT_UID);
}
else
{
foreach ($part->parts as $alternative_key => $alternative_part)
{
if ($alternative_part->subtype == 'PLAIN')
{
echo '<h2>' . $alternative_part->subtype . ' ' . $alternative_part->encoding . '</h2>';
$result['text'] = imap_fetchbody($this->connection, $id, ($key + 1) . '.' . ($alternative_key + 1), FT_UID);
}
else if ($alternative_part->subtype == 'HTML')
{
echo '<h2>' . $alternative_part->subtype . ' ' . $alternative_part->encoding . '</h2>';
$result['html'] = imap_fetchbody($this->connection, $id, ($key + 1) . '.' . ($alternative_key + 1), FT_UID);
}
}
}
}
}
}
else
{
$result['text'] = imap_body($this->connection, $id, FT_UID);
}
$result['text'] = imap_qprint($result['text']);
$result['html'] = imap_qprint(imap_8bit($result['html']));
return $result;
}
return false;
}
私はそれを深くテストしたことがなく、いくつかのバグがあると確信していますが、それは始まりかもしれません...このコードを適応した後、あなたは $result
インデックス(text
, html
, attachments
)マイムの境界を無傷に保つことを心配することなく、転送スクリプト(たとえばSwiftMailerを使用)を使用します。
他のヒント
これは実際には答えではありませんが、代替方法の提案です。既存のアカウント内の異なるフォルダーにメッセージを移動した場合、エラーがはるかに簡単で、エラーが発生しやすくなります(つまり、配信の問題はありません)。すなわち、Cronが実行され、すべてのメールを受信トレイで処理します。停止した場合、必要な作業を行い、その後(IMAP関数を介して)電子メールを「Processed」または同様の名前のサブフォルダーに単純に移動するだけです。それ以外の場合は、電子メールを「Check Thate」または同様の名前のサブフォルダーに移動します。その場合、転送やさらなる配信、2番目のアカウントを心配する必要はありません。また、誰もが処理された、処理されていない、保留中のメールを直接監視できます。
使用を使用して機能を見てみましょう SwiftMailer 図書館 ?
私は過去にこれを使用し、あなたが説明したようなアプリケーションではなく、良い結果を得ましたが、私はそれをPHPベースの「メーリングリスト」に使用して、被験者をチェックして適切なグループに送信しました。
しかし、私は新しいメッセージを作成しましたが、転送しませんでした。それが役立つことを願っています。
これは私に以前に起こりました。それを修正するために、imap_fetchbody()を使用した後、電子メールの本文でimap_base64()を実行する必要がありました。
$body = imap_fetchbody($imap, 1, 1);
$headers = imap_headerinfo($imap, 1);
$body = imap_base64($body);
IOハンドラーを使用して、電子メールのコンテンツを文字列としてキャプチャし、ヘッダーを分割し、PHP 'Mail()'関数を使用して送信します。
そうでなければ、あなたが本当にPHP-IMAPでこれをやりたいなら、
PHP-IMAP拡張機能は、Pine Emailクライアントソフトウェアの一部であるLibc-Clientであり、Pineを使用してそれを行うために必要なマニュアルの手順を把握し、Pineが作成するCクライアントコールを調べます。これにより、PHPで必要な手順が表示されます。
C-Clientドキュメントはかなり最小限であり、Pine Sourceに行くことは、使用法の詳細を取得するための最良の方法です。
PHP拡張の著者は、このパスをブロックするものを省略または変更した「あなたの便利さまたは保護のために」を持っていることに気付くかもしれません。