【问题标题】:PHP pipe to script emailPHP管道到脚本电子邮件
【发布时间】:2020-10-19 12:30:24
【问题描述】:

我正在尝试将来自 support@example.com 的所有电子邮件转发到 PHP 脚本以插入 MySql。

我的脚本有效,但我有两个问题。

  1. 发件人电子邮件地址显示发件人的姓名,而不是电子邮件地址。

  2. 电子邮件正文内容显示为例如。

    --00000000000095430105a9347fe3 内容类型:文本/纯文本; charset="UTF-8"

这是一封测试邮件

--00000000000095430105a9347fe3 内容类型:文本/html; charset="UTF-8"

这是一封测试邮件

--00000000000095430105a9347fe3--

不仅仅是电子邮件的正文这是一封测试电子邮件

这是我的代码:

// handle email
 $lines = explode("\n", $email);

 // empty vars
 $from = "";
 $subject = "";
 $headers = "";
 $message = "";
 $splittingheaders = true;
 for ($i=0; $i < count($lines); $i++) {
 if ($splittingheaders) {
    // this is a header
    $headers .= $lines[$i]."\n";


    // look out for special headers
    if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
        $subject = $matches[1];
    }
    if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
        $from = $matches[1];
    }
    if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
        $to = $matches[1];
    }
    } else {
        // content/main message body information
        $message .= $lines[$i]."\n";
  
    }

    if (trim($lines[$i])=="") {
    // empty line, header section has ended
    $splittingheaders = false;
    }
}

我试过了

$message = imap_fetchbody($mbox,1,'1');

$message = strip_tags(quoted_printable_decode(imap_fetchbody($mbox,1,"1")));
$message = strip_tags($message, '<body>');
$message = explode(">", $message);
$message = explode("<", $message[1]);
$message = str_replace("&nbsp;", "", $message[0]);
$message = html_entity_decode($message);
$message = trim($message);

我试过了,但不知道如何让它工作:

   $emailnumberPattern = "--[0]{12}";
   $replacement = " ";
   preg_replace($emailnumberPattern, $replacement, $string);
   $message .= $lines[$i]."\n";

欢迎任何帮助显示发件人电子邮件以及从电子邮件正文中删除不需要的内容。

【问题讨论】:

  • 我测试了你的代码,$from 正确包含First Last &lt;first.last@company.org&gt;
  • 谢谢。我的问题是,当我从支持面板回复时,它无法识别电子邮件格式 First Last &lt;first.last@company.org&gt;。所以我想删除First Last,只想要first.last@company.org
  • 这很容易解决:if (preg_match('/ &lt;(.*)&gt;/', $from, $matches)){$from = $matches[1];}.
  • 太棒了。谢谢,我现在会改变它。你能帮我解决删除问题吗--00000000000095430105a9347fe3 Content-Type: text/plain; charset="UTF-8" --00000000000095430105a9347fe3 内容类型:文本/html; charset="UTF-8" --00000000000095430105a9347fe3--。这样只插入消息,在这种情况下这是一封测试电子邮件
  • @simlev 我试过$messages .= $lines[$i]."\n"; $message = preg_replace('/Content-Type: text/plain; charset="UTF-8" /',' ',$messages); 没有成功有什么建议吗?

标签: php email


【解决方案1】:

解析电子邮件并非易事,只需几个正则表达式即可解决。您绝对应该使用专用的extensionprogram。此外,您应该避免将整个消息加载到单个字符串(或数组)中。

This one 只是一个 composer 命令:composer require zbateson/mail-mime-parser

require __DIR__ . '/vendor/autoload.php';
$handle = fopen('php://stdin', 'r');
$message = \ZBateson\MailMimeParser\Message::from($handle);
fclose($handle);
$from = $message->getHeaderValue('from');
$body = $message->getTextContent();

也就是说,您可以使用您的代码获得一些结果,我已尽可能少地对其进行了修改:

 $lines = explode("\n", $email);

 // empty vars
 $from = "";
 $subject = "";
 $headers = "";
 $message = "";
 $splittingheaders = true;
 for ($i=0; $i < count($lines); $i++) {
 if ($splittingheaders) {
    // this is a header
    $headers .= $lines[$i]."\n";


    // look out for special headers
    if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
        $subject = $matches[1];
    }
    if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
        $from = $matches[1];
    }
    if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
        $to = $matches[1];
    }
    } else {
        if (preg_match('/Content-Type: text\/plain; charset=/', $lines[$i])) {
            $m = true;
            continue;
        }
        if (preg_match('/Content-Type:/', $lines[$i])) {
            $m = false;
        }
        if ($m) {
            $message .= $lines[$i]."\n";
        }
    }

    if (trim($lines[$i])=="") {
    // empty line, header section has ended
    $splittingheaders = false;
    }
 }
 if (preg_match('/ <(.*)>/', $from, $matches)){
     $from = $matches[1];
 }

无法保证这些结果,并且高度依赖于输入格式。要获得可靠的解决方案,请使用经过充分测试的解析器。

【讨论】:

  • 我将 for ($i=0; $i &lt; count($lines); $i++) 替换为 foreach($lines as $line) 然后使用 $line 代替 $lines[$i] (也可以将三个正则表达式替换为 preg_match('/^(Subject|To|From): (.*)/', $lines, $match); ${strtolower($match[1])} = $match[2]; 但变量变量:/)
猜你喜欢
  • 2016-03-30
  • 2011-08-01
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 2012-10-16
相关资源
最近更新 更多